我一直在用kbhit()测试一些东西,发现了一个延迟无限循环的奇怪行为。在这个代码示例中,我将循环延迟到每秒运行30次。
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
_Bool IsKeyDown(char c)
{
if(kbhit())
{
char ch1 = getch();
if(ch1 == c)
return 1;
}
return 0;
}
/*
*
*/
int main(int argc, char** argv) {
while(1)
{
if(IsKeyDown('a'))
{
printf("HELLO\n");
}
if(IsKeyDown('b'))
{
printf("HI\n");
}
Sleep(1000 / 30);
}
return (EXIT_SUCCESS);
}问题是,尽管循环中的第一个if语句运行良好,但第二个if语句几乎不起作用。在本例中,如果您按住'a‘键,HELLO将无限期打印。如果你按住“b”键,HI几乎不会被打印出来。
为什么会发生这种行为?
发布于 2014-01-12 20:00:43
之所以会发生这种情况,是因为当kbhit返回true时,您的IsKeyDown会消耗缓冲区中的下一个字符。因为连续调用IsKeyDown两次,第一次调用会“吃掉”'b',所以当运行第二次调用时,缓冲区中没有数据。
您需要重新组织代码,以便在每次循环迭代中只调用一次IsKeyDown。您的循环应该存储其返回值,并将存储的值与所需的字符(即'a'和'b')进行比较:
int GetKeyDown() {
if(kbhit())
{
return getch();
}
return -1;
}
while(1)
{
int keyDown = GetKeyDown();
if(keyDown == 'a')
{
printf("HELLO\n");
}
if(keyDown == 'b')
{
printf("HI\n");
}
Sleep(1000 / 30);
}发布于 2014-01-12 20:01:39
因为第一个IF会消耗正在被按下的键。更改您的代码,以便只读一次密钥:
int main(int argc, char** argv) {
char key;
while(1)
{
if (khbit())
key = getch();
else
key = 0;
if(key == 'a')
{
printf("HELLO\n");
}
if(key == 'b')
{
printf("HI\n");
}
Sleep(1000 / 30);
}
return (EXIT_SUCCESS);
}https://stackoverflow.com/questions/21074310
复制相似问题