我试着写一个简单的程序,当没有按键时执行一个特定的任务,当任何按键被按下时执行另一个任务。这是我到目前为止所拥有的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
int kbhit (void);
int main()
{
char c;
while(1)
{
while (!kbhit())
{
printf("%d", 0);
}
c = getchar();
printf("%c", c);
if(c == 'x' || c == 'X')
break;
sleep(0);
}
return 0;
}
int kbhit (void)
{
struct timeval tv;
fd_set rdfs;
tv.tv_sec = 0;
tv.tv_usec = 1000;
FD_ZERO(&rdfs);
FD_SET (STDIN_FILENO, &rdfs);
select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &rdfs);
}
这种实现对于反复检测单个按键是很好的,但是如果您一直按键盘键,则在检测按键之间存在明显的间隔。即使一直按下该键,仍会将0打印到控制台。例如,如果我一直按下'W',输出看起来像这样:000000000000000WWWWWWWW00000000000000000WWWWWWWW00000000...
我如何修复这个问题,以便当键盘键被持续按下时,kbhit()总是返回0?
2条答案
按热度按时间lymnna711#
您的
kbhit
(显然,甚至Windows的原始kbhit
)不会检测是否按下了一个键,而只会检测stdin
上是否有新内容可读取。这将只是25次每秒左右的情况下,这取决于您的自动重复设置。在示例代码中将stdout
设为无缓冲将使这一点更加明显(000000W00000000W000000000W
)我如何修复这个问题,以便当键盘键被持续按下时,kbhit()总是返回0?
这是不可能做到可移植的。在Linux中,可以使用
/dev/input
下的设备文件来完成。它将注册所有键,甚至是一个单独的SHIFT键注意,这实际上是一个键盘记录器,所以你必须以root身份运行(或使程序setuid)。然后,它将记录所有的击键,即使它没有键盘焦点。哎呀!注意:下面的示例基于Kevin考克斯的keystate.c
zvms9eto2#
Here是一个用于Linux的键盘记录器,用于字母数字键。它可以通过从this header file复制到正确的位置来扩展到其他键码。