В очередной раз столкнулся с проблемой блокирующего чтения символа из юниксовой консоли. Кто имел счастье писать на борландовском Паскале под 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
отвечает за эхо ввода, т.е., в данном случае, отображение на экране введенного символа. Убираем/оставляем по вкусу.