Как уже указано, можно использовать sigaction
для захвата ctrl-c, или select
для захвата любого стандартного входа.
Примечание однако, что с последним методом также необходимо установить TTY так, чтобы это было в character-at-a-time, а не line-at-a-time режиме. Последний является значением по умолчанию - если Вы вводите в строке текста, это не становится отправленным в stdin под управлением программы, пока Вы не нажимаете Enter.
необходимо было бы использовать эти tcsetattr()
функция, чтобы выключить режим ICANON, и вероятно также отключить ЭХО также. Из памяти также необходимо задержать терминал в режим ICANON, когда программа выходит!
Только для полноты, вот некоторый код, который я только что поднял (nb: никакая проверка ошибок!), который настраивает Unix TTY и эмулирует функции DOS <conio.h>
kbhit()
и getch()
:
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <termios.h>
struct termios orig_termios;
void reset_terminal_mode()
{
tcsetattr(0, TCSANOW, &orig_termios);
}
void set_conio_terminal_mode()
{
struct termios new_termios;
/* take two copies - one for now, one for later */
tcgetattr(0, &orig_termios);
memcpy(&new_termios, &orig_termios, sizeof(new_termios));
/* register cleanup handler, and set the new terminal mode */
atexit(reset_terminal_mode);
cfmakeraw(&new_termios);
tcsetattr(0, TCSANOW, &new_termios);
}
int kbhit()
{
struct timeval tv = { 0L, 0L };
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
return select(1, &fds, NULL, NULL, &tv);
}
int getch()
{
int r;
unsigned char c;
if ((r = read(0, &c, sizeof(c))) < 0) {
return r;
} else {
return c;
}
}
int main(int argc, char *argv[])
{
set_conio_terminal_mode();
while (!kbhit()) {
/* do some work */
}
(void)getch(); /* consume the character */
}
select()
слишком немного низкий уровень для удобства. Я предлагаю, чтобы Вы использовали ncurses
библиотека, чтобы поместить терминал в cbreak режим и режим задержки, затем звонить getch()
, который возвратится ERR
, если никакой символ не будет готов:
WINDOW *w = initscr();
cbreak();
nodelay(w, TRUE);
В той точке можно звонить getch
без блокирования.
В системах UNIX можно использовать sigaction
вызов для регистрации обработчика сигналов для SIGINT
сигнал, который представляет сочетание клавиш Control+C. Обработчик сигналов может установить флаг, который будет проверен в повреждении добирающегося цикла соответственно.
Вы, вероятно, хотите kbhit();
//Example will loop until a key is pressed
#include <conio.h>
#include <iostream>
using namespace std;
int main()
{
while(1)
{
if(kbhit())
{
break;
}
}
}
, это не может работать над всеми средами. Портативный путь состоял бы в том, чтобы создать контролирующий поток и установить некоторый флаг на getch();
Библиотекой проклятий можно пользоваться с этой целью. Конечно, select()
и обработчики сигналов может использоваться слишком до некоторой степени.
Если Вы счастливы просто захватывающая Ctrl-C, это - заключенная сделка. Если Вы действительно хотите не блокировать ввод-вывод, но Вы не хотите библиотеку проклятий, другая альтернатива должна переместить блокировку, запас и баррель к AT& библиотека T sfio
. Это - хорошая библиотека, скопированная на C stdio
, но более гибкая, ориентированная на многопотоковое исполнение, и работает лучше. (sfio обозначает безопасный, быстрый ввод-вывод.)
Нет никакого портативного способа сделать, это, но выбор () могло бы быть хорошим путем. См. http://c-faq.com/osdep/readavail.html для более возможных решений.