@lori_jast
В Linux можно реализовать аналог функции kbhit()
с помощью использования системных вызовов для неканонического ввода. Вот пример кода на языке C, который позволяет проверять наличие непрочитанных символов во входном потоке ввода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include <stdio.h> #include <unistd.h> #include <termios.h> #include <fcntl.h> int kbhit() { struct termios oldt, newt; int ch; int oldf; tcgetattr(STDIN_FILENO, &oldt); // сохранить старые настройки терминала newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); // изменить настройки для неканонического ввода без отображения символов tcsetattr(STDIN_FILENO, TCSANOW, &newt); // применить новые настройки oldf = fcntl(STDIN_FILENO, F_GETFL, 0); // получить старые флаги файлового дескриптора fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); // добавить флаг неблокирующего чтения ch = getchar(); // попытаться прочитать символ из входного потока tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // вернуть старые настройки терминала fcntl(STDIN_FILENO, F_SETFL, oldf); // вернуть старые флаги файлового дескриптора if (ch != EOF) { ungetc(ch, stdin); // вернуть символ обратно во входной поток return 1; } return 0; } int main() { while (1) { if (kbhit()) { printf("Key pressed! "); break; } // simulate some other work usleep(100000); // sleep for 100 milliseconds } return 0; } |
В этом примере функция kbhit()
изменяет настройки терминала на неканонический режим без отображения символов и устанавливает флаг неблокирующего чтения для входного потока стандартного ввода. Затем она пытается прочитать символ из входного потока. Если символ доступен, то он возвращается, иначе функция возвращает 0.
Функция main()
в данном примере использует kbhit()
для проверки наличия нажатой клавиши в цикле. Если клавиша была нажата, программа выводит сообщение и завершает свою работу. Если клавиша не была нажата, программа продолжает выполнять другую работу (в данном случае указано задержку в 100 миллисекунд).
@lori_jast
Дополнительно отмечу, что данная реализация функции kbhit() использует функции tcgetattr(), tcsetattr() для работы с настройками терминала и fcntl() для управления флагами файлового дескриптора. Такой подход позволяет осуществлять проверку наличия непрочитанных символов во входном потоке ввода без блокировки программы в ожидании ввода данных.
Кроме этого, можно также воспользоваться библиотекой ncurses
, которая предоставляет более высокоуровневый инструментарий для работы с терминалом. В ncurses
также есть функции, позволяющие организовать неканонический ввод и проверку наличия нажатых клавиш. Этот подход может быть удобен, если требуется более сложная обработка ввода с поддержкой интерактивного пользовательского интерфейса.