Линейная дисциплина для оконечного устройства часто работает в каноническом режиме по умолчанию. В этом режиме драйвер терминала не представляет буфер пользовательскому пространству до появления новой строки (нажата клавиша Enter ).
Вы можете установить терминал в необработанный (неканонический) режим, используя <a href="http://www.opengroup.org/onlinepubs/000095399/functions/tcsetattr.html" rel="noreferrer"><b>tcsetattr()</b></a>
для управления структурой termios
. Очистка флагов ECHO
и ICANON
соответственно отключает отображение символов по мере их ввода и приводит к тому, что запросы на чтение удовлетворяются непосредственно из входной очереди. При установке значений VTIME
и VMIN
в ноль в массиве c_cc
запрос на чтение (fgetc()
) немедленно возвращается, а не блокируется; эффективно опросить стандартный ввод. Вызов fgetc()
вернет EOF
, если символ не доступен в потоке.
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>
int getkey() {
int character;
struct termios orig_term_attr;
struct termios new_term_attr;
/* set the terminal to raw mode */
tcgetattr(fileno(stdin), &orig_term_attr);
memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios));
new_term_attr.c_lflag &= ~(ECHO|ICANON);
new_term_attr.c_cc[VTIME] = 0;
new_term_attr.c_cc[VMIN] = 0;
tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);
/* read a character from the stdin stream without blocking */
/* returns EOF (-1) if no character is available */
character = fgetc(stdin);
/* restore the original terminal attributes */
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
return character;
}
int main()
{
int key;
/* initialize the random number generator */
srand(time(NULL));
for (;;) {
key = getkey();
/* terminate loop on ESC (0x1B) or Ctrl-D (0x04) on STDIN */
if (key == 0x1B || key == 0x04) {
break;
}
else {
/* print random ASCII character between 0x20 - 0x7F */
key = (rand() % 0x7F);
printf("%c", ((key < 0x20) ? (key + 0x20) : key));
}
}
return 0;
}
Примечание. В этом коде пропущена проверка ошибок для простоты.