Эквивалент Windows getch() для сбоев Mac / Linux
Вопрос
Я использую getch()
и мое приложение мгновенно выходит из строя.В том числе и при выполнении:
int main()
{
getch();
}
Я не могу найти ссылку, но предположительно проблема в том, что для этого нужно отключить буферизацию или что-то странное в этом роде, и я все еще хочу cout
работать вместе с кросс-платформенным кодом.
Мне сказали использовать std::cin.get()
, но я бы хотел, чтобы приложение завершало работу при нажатии клавиши, а не когда пользователь вводит букву или цифру, а затем нажимает enter для завершения.
Есть ли какая-нибудь функция для этого?Код должен работать под управлением Mac (моя ОС) и Windows.
Связывание / компиляция не является проблема;Я включаю в себя <curses.h>
и связать с -lcurses
в XCode, в то время как Windows использует <conio.h>
.
Решение
Вы смотрели в <curses.h>
, чтобы узнать, что делает функция getch()
?
Подсказка: OSX и Linux - это не то же самое, что Windows.
В частности, в качестве макроса в stdscr
мы находим:
#define getch() wgetch(stdscr)
Теперь в вашей системе есть реальная функция initscr()
в библиотеке curses, но она ожидает установки atexit()
, и это делается с помощью функций инициализации curses (read(0, &c, 1)
и родственники), и это не сделано вашим кодом. Таким образом, ваш код вызывает неопределенное поведение, вызывая процедуры curses до того, как будет выполнена правильная инициализация, что приведет к сбою.
(Хорошая подсказка от dmckee - это помогло получить строку ссылки из acidzombie24, что было важно.)
Чтобы добраться до точки, в которой можно прочитать одно нажатие клавиши и программа завершена полностью, вы должны проделать большую работу в Unix (OSX, Linux). Вам нужно было бы перехватить начальное состояние терминала, настроить функцию <=> - или какой-либо подобный механизм - для восстановления состояния терминала, перевести терминал из готового режима в необработанный режим, а затем вызвать функцию для чтения персонаж (возможно, просто <=>), и сделать свой выход. Могут быть и другие способы сделать это, но это, безусловно, потребует некоторых операций настройки и демонтажа.
Одна книга, которая может помочь, - Расширенное программирование Unix, 2-е издание Марк Рочкинд; он охватывает обработку терминала на необходимом уровне. В качестве альтернативы, вы можете использовать <=> правильно - это будет проще, чем решение по принципу «сделай сам», и, возможно, будет более надежным.
Другие советы
Вы не выставляли
#include <stdio.h>
или
#include <curses.h>
или аналогичная строка.Вы уверены, что ссылаетесь на библиотеку, которая включает в себя getch()
?
Используйте функцию cin.get (), например:
#include <iostream>
using namespace std;
int main()
{
char input = cin.get();
cout << "You Pressed: " << input;
}
Затем программа будет ждать, пока вы нажмете клавишу.
После этого нажатая клавиша будет выведена на экран.
Функция getch
недоступна в Unix-подобных системах, но вы можете заменить ее консольными командами через ваш компилятор с функцией system
.
Использование:
В Windows вы можете использовать system("pause");
В Unix-подобных системах (таких как OSX) вы можете использовать system("read -n1 -p ' ' key");
Примечание. <stdlib.h>
объявлено в <=>.