输入缓冲区中的待处理字符

时间:2015-12-12 13:07:11

标签: c++ buffer getch

我正在使用C ++构建一个简单的游戏,我认为输入缓冲区存在很大问题。下面的代码在循环中工作,我正在检查用户是否按下左或右键以移动我的角色。如果是这样,我使用switch语句来执行适当的操作。但问题是,当我按下左键一段时间然后将其改为右键时,我的角色仍然会向左移动一段时间。我想这是因为当我停止按键时,输入缓冲区中仍然有字符。我试图解决这个问题,以某种方式清理缓冲区,但我在互联网上发现的一切都不起作用。例如,我试图使用

FlushConsoleInputBuffer(stdin);

std::cin.clear();
std::cin.sync();

这一切都失败了因为我错了,或者根本不符合我的目的。你能解决我的问题吗?

我的代码:

if(GetAsyncKeyState(VK_RIGHT)!= 0 || GetAsyncKeyState(VK_LEFT) != 0){
    getch();
    int key = getch();
    switch(key){
        case KEY_LEFT:                 
            //some code
            break;

        case KEY_RIGHT:
            //some code
            break;

        case KEY_F1:
            //some code
            break;

        default:
            break;

    }

}

1 个答案:

答案 0 :(得分:0)

我假设您正在使用Windows运行此功能。问题是您异步读取键盘状态,但管道中可能仍有一些键。

使用getch()微软推荐使用_getch() )阅读特殊密钥需要阅读两次:

  

当读取功能键或箭头键时,每个功能必须是   叫了两次;第一个调用返回0或0xE0,第二个调用返回   返回实际的密钥代码。

当你跳过第一个字符而不检查其有效性时,缓冲输入可能会造成一些破坏。你必须抛弃这种意想不到的输入:

if (...) {
    int key; 
    do key0 = _getch();
       while (key != 0 && key != 0xE0);   // make sure we read special keys only.
    key = _getch();
    switch(...) {  // don't forget default as key could still be unexpected special key 
    }
}

但使用GetAsyncKeyState()会使您的程序特定于Windows。因此,如果您的代码仍然没有足够的反应性,尽管有这种变化,那么您也可以考虑不使用getch()并通过直接使用GetKeyState()获得更具反应性的程序。

if (GetKeyState(VK_RIGHT)!=0) {
   // somecode
} else if (...) 
...