这是我修改为实际 C 而不是 C++ 的代码版本,因为它只是出于粗心使用 bool true/false 和 struct 关键字而成为 C++。
哦,是的,不要把它放在头文件中。将它放在一个名为 kbhit.c 的文件中,然后删除或注释掉 test main 函数。在头文件中只写一行:
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;
}
对我来说它看起来是正确的,valgrind 没有抱怨。我没有 Dr. Memory 可以检查。
这段代码的工作原理是它首先用于tcgetattr
读取 termios(我认为是终端输入输出设置)结构。然后它通过取消设置 ICANON 位来修改它。佳能是终端的规范设置,包括行缓冲。然后它将新的 termios 值写回终端。与tcsetattr
.
该ioctl
调用获取缓冲区中等待的字节数。如果有字节在等待,那么有人按下了某种键。