输入缓冲区中的挂起字符

Pending characters in input buffer

本文关键字:挂起 字符 缓冲区 输入      更新时间:2023-10-16

我正在用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;
    }
}

我假设您正在使用windows运行此程序。问题是,您异步读取keyboerd状态,但管道中可能仍有一些密钥。

使用getch()读取特殊密钥(microsoft建议使用_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()会使您的程序具有特定的窗口。因此,如果您的代码尽管发生了此更改,但仍然不够被动,那么您还可以考虑不使用getch(),直接使用GetKeyState()来获得更被动的程序。

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