Следующая короткая программа не требует ни ncurses, ни потоков.Однако для этого необходимо изменить атрибуты терминала - используя tcsetattr()
.Это будет работать в Linux и Unix-подобных системах, но не в Windows, которая не включает заголовочный файл termios.h
.(Возможно, смотрите этот пост , если вы заинтересованы в этом предмете.)
#include <stdio.h>
#include <string.h>
#include <termios.h>
int main(int argc, char *argv[]) {
struct termios orig_attr, new_attr;
int c = '\0';
// or int n = atoi(argv[1]);
int n = 5;
tcgetattr(fileno(stdin), &orig_attr);
memcpy(&new_attr, &orig_attr, sizeof(new_attr));
new_attr.c_lflag &= ~(ICANON | ECHO);
new_attr.c_cc[VMIN] = 0;
// Wait up to 10 deciseconds (i.e. 1 second)
new_attr.c_cc[VTIME] = 10;
tcsetattr(fileno(stdin), TCSANOW, &new_attr);
printf("Starting with n = %d\n", n);
do {
c = getchar();
if (c != EOF) {
n++;
printf("Key pressed!\n");
printf("n++ => %d\n", n);
} else {
n--;
printf("n-- => %d\n", n);
if (n == 0) {
printf("Exiting ...\n");
break;
}
if (feof(stdin)) {
//puts("\t(clearing terminal error)");
clearerr(stdin);
}
}
} while (c != 'q');
tcsetattr(fileno(stdin), TCSANOW, &orig_attr);
return 0;
}
Жизненно важные моменты состоят в том, что
new_attr.c_lflag &= ~(ICANON | ECHO);
выводит терминал из канонического режима(и отключает символ 'echo'),
new_attr.c_cc[VMIN] = 0;
переводит его в режим опроса (а не в 'блокирование'), а
new_attr.c_cc[VTIME] = 10;
дает программе команду ждать до 10 децисекунддля ввода.
Обновление (2019-01-13)
- добавление
clearerr(stdin)
для очистки EOF
в stdin
(кажется необходимымна некоторых платформах)