Вот версия кода, которую я изменил, чтобы она была реальным C, а не C ++, поскольку это был C ++ из-за небрежности с ключевыми словами bool true / false и struct.
И, о да, донне помещайте это в заголовочный файл.Поместите его в файл с именем kbhit.c и удалите или закомментируйте основную функцию теста.А в заголовочном файле просто напишите строку:
int _kbhit(void);
Или вам может понадобиться:
extern "C" int _kbhit(void);
Это все, что вам нужно в заголовке.
/**
Linux (POSIX) implementation of _kbhit().
Morgan McGuire, morgan@cs.brown.edu
*/
#include <stdbool.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
int _kbhit(void) {
static bool initialized = false;
if (! initialized) {
// Use termios to turn off line buffering
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
setbuf(stdin, NULL);
initialized = true;
}
int bytesWaiting;
ioctl(STDIN_FILENO, FIONREAD, &bytesWaiting);
return bytesWaiting;
}
//////////////////////////////////////////////
// Simple demo of _kbhit()
int main() {
printf("Press any key");
while (! _kbhit()) {
printf(".");
fflush(stdout);
usleep(1000);
}
printf("\nDone.\n");
return 0;
}
Это выглядит правильно для меня, и Вальгринд не жалуется.У меня нет доктора Памяти.
Принцип работы этого кода заключается в том, что он сначала использует tcgetattr
для чтения структуры termios (настройки вывода терминала, я думаю).Затем он изменяет его, сбрасывая биты ICANON.Canon - это каноническая настройка для терминалов, которая включает буферизацию строки.Затем он записывает новые значения termios обратно в терминал.с tcsetattr
.
Вызов ioctl
получает количество байтов, ожидающих в буфере.Если ожидают байты, то кто-то нажал какие-то клавиши.