21xrx.com
2024-11-05 20:41:11 Tuesday
登录
文章检索 我的文章 写文章
如何在C++中实现非阻塞的getch函数
2023-07-08 15:36:11 深夜i     --     --
C++ 非阻塞 getch函数 输入缓存 信号处理

在很多情况下,使用getch函数可以使程序更加方便地接受键盘输入。然而,在C++中的getch函数通常是阻塞的,这意味着当用户输入时,程序会暂停等待用户输入完毕才继续执行后面的代码。如果你希望在程序执行时能够同时响应其他操作,那么你需要实现非阻塞的getch函数。

实现非阻塞的getch函数

要实现非阻塞的getch函数,你需要使用C++的标准库和一些Windows API特性。以下是使用Visual Studio的Windows用户可以使用的代码实现:


#include <conio.h>

#include <Windows.h>

#include <iostream>

int main() {

  bool running = true;

  while (running) {

    if (_kbhit()) { // 如果有按键被按下

      char ch = _getch();

      if (ch == 'q')

        running = false;

      

      std::cout << ch << std::endl;

    }

    Sleep(100); // 等待一段时间,以避免过早刷新屏幕

  }

  return 0;

}

这段代码首先检查是否有键盘输入按下,如果有,则读取该字符并将其打印到屏幕上。如果按下‘q’键,则设置running变量为false并退出程序。

但是这个解决方案仍然有一个小问题:如果用户太快地按下键盘上的按键,程序可能不会及时检测到它。这是由于_kbhit函数只检测键盘缓冲区中是否有数据,如果在函数执行时数据还没有到达缓冲区,就无法及时检测到用户的输入。为了解决这个问题,你可以使用Windows API中的SetConsoleMode函数。SetConsoleMode函数可以将控制台的输入模式更改为真正的“无缓冲输入模式”,这会立即向你提供键盘按键的数据。

可以使用以下代码更改控制台的模式:


HANDLE consoleHandle = GetStdHandle(STD_INPUT_HANDLE);

DWORD mode = 0;

GetConsoleMode(consoleHandle, &mode);

SetConsoleMode(consoleHandle, mode & (~ENABLE_LINE_INPUT));

此代码会将控制台模式更改为不使用输入缓冲区。然后,你就可以使用_kbhit和_getch函数读取按键,而无需使用Sleep函数等待新数据。

总结

虽然getch函数在很多情况下很方便,但是它的阻塞特性可能导致程序在处理用户输入时出现延迟。通过使用_kbhit和_getch函数,同时设置控制台模式为真正的“无缓冲输入模式”,你可以实现非阻塞的getch函数。这将允许程序在处理用户输入时更加灵活,同时也能够快速响应其他操作。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复
    相似文章