В очередной раз столкнулся с проблемой блокирующего чтения символа из юниксовой консоли. Кто имел счастье писать на борландовском Паскале под DOS наверняка помнит функцию
Вся соль подхода в структуре
Наш враг в данном случае — бит
Бит
ReadKey(), блокирующую выполнение программы до нажатия эникея. У меня пару раз всплывало это требование и в юниксовой консоли, но сишная функция getchar() блокирует выполнение до нажатия Enter, что не очень желательно в некоторых случаях.#include <stdio.h> #include <termios.h> #include <unistd.h> int main() { struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, 0, &term); if (getchar()) { printf(«Hello world!»); } return 0; }
Вся соль подхода в структуре
termios, которая описывает параметры терминала. Поле c_lflag отвечает за так называемые локальные опции, т.е. за то, как вводимые символы будут обработаны драйвером.Наш враг в данном случае — бит
ICANON, отвечающий за выбор канонического или неканонического (raw) режима ввода. Канонический режим для stdin устанавливается по умолчанию и подразумевает, помимо всего прочего, строчный буфер, т.е. требование нажимать Enter каждый раз при желании скормить что-либо getchar(). Соответственно, требуется перевести stdin в неканонический режим.Бит
ECHO того же поля termios отвечает за эхо ввода, т.е., в данном случае, отображение на экране введенного символа. Убираем/оставляем по вкусу.