【问题标题】:Pending characters in input buffer输入缓冲区中的待处理字符
【发布时间】:2015-12-12 13:07:10
【问题描述】:

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

    }

}

【问题讨论】:

  • C 没有 I/O 流。如果您不打算使用 OOP,那么使用 C++ 而不是 C 的目的是什么?
  • 好吧,您正在使用 OOP:std::cinstd::istream 类型的对象。

标签: c++ buffer getch


【解决方案1】:

我假设您使用 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() 会使您的程序已经是特定于窗口的。因此,如果尽管进行了这些更改,您的代码仍然不够反应,那么您也可以考虑不使用 getch() 并通过直接使用 GetKeyState() 来获得更具反应性的程序。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 2015-02-03
    相关资源
    最近更新 更多