首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >延迟无限循环中奇怪的kbhit()行为

延迟无限循环中奇怪的kbhit()行为
EN

Stack Overflow用户
提问于 2014-01-12 19:54:43
回答 2查看 811关注 0票数 2

我一直在用kbhit()测试一些东西,发现了一个延迟无限循环的奇怪行为。在这个代码示例中,我将循环延迟到每秒运行30次。

代码语言:javascript
复制
#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几乎不会被打印出来。

为什么会发生这种行为?

EN

回答 2

Stack Overflow用户

发布于 2014-01-12 20:00:43

之所以会发生这种情况,是因为当kbhit返回true时,您的IsKeyDown会消耗缓冲区中的下一个字符。因为连续调用IsKeyDown两次,第一次调用会“吃掉”'b',所以当运行第二次调用时,缓冲区中没有数据。

您需要重新组织代码,以便在每次循环迭代中只调用一次IsKeyDown。您的循环应该存储其返回值,并将存储的值与所需的字符(即'a''b')进行比较:

代码语言:javascript
复制
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);
}
票数 5
EN

Stack Overflow用户

发布于 2014-01-12 20:01:39

因为第一个IF会消耗正在被按下的键。更改您的代码,以便只读一次密钥:

代码语言:javascript
复制
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);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21074310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档