基于 Christophe 的答案的紧凑解决方案是
#include <sys/ioctl.h>
#include <termios.h>
bool kbhit()
{
termios term;
tcgetattr(0, &term);
termios term2 = term;
term2.c_lflag &= ~ICANON;
tcsetattr(0, TCSANOW, &term2);
int byteswaiting;
ioctl(0, FIONREAD, &byteswaiting);
tcsetattr(0, TCSANOW, &term);
return byteswaiting > 0;
}
与那个答案不同,这不会在程序退出后使终端处于奇怪的状态。但是,它仍然将字符留在输入缓冲区中,因此按下的键将不受欢迎地出现在下一个提示行上。
解决此问题的另一种解决方案是
void enable_raw_mode()
{
termios term;
tcgetattr(0, &term);
term.c_lflag &= ~(ICANON | ECHO); // Disable echo as well
tcsetattr(0, TCSANOW, &term);
}
void disable_raw_mode()
{
termios term;
tcgetattr(0, &term);
term.c_lflag |= ICANON | ECHO;
tcsetattr(0, TCSANOW, &term);
}
bool kbhit()
{
int byteswaiting;
ioctl(0, FIONREAD, &byteswaiting);
return byteswaiting > 0;
}
用法如下
enable_raw_mode();
// ...
if (kbhit()) ...
// ...
disable_raw_mode();
tcflush(0, TCIFLUSH); // Clear stdin to prevent characters appearing on prompt
现在,在执行第一行和最后一行之间键入的任何字符都不会显示在终端中。但是,如果您使用 Ctrl+C 退出,终端将处于奇怪的状态。(叹)