@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 также есть функции, позволяющие организовать неканонический ввод и проверку наличия нажатых клавиш. Этот подход может быть удобен, если требуется более сложная обработка ввода с поддержкой интерактивного пользовательского интерфейса.