Linux终端下如何用C++检测多个键盘按键同时按下?
扩展C++键盘检测代码:支持多键单独/同时按下检测
原代码仅能实现单键单次输入检测,无法识别多键同时按下的场景。要实现检测b、n单独按下,以及两者同时按下的功能,需要将终端输入调整为非阻塞模式,并维护按键状态集合,具体实现如下:
修改后的完整代码
#include <iostream> #include <termios.h> #include <unistd.h> #include <fcntl.h> #include <cstring> using namespace std; // 维护按键状态:索引为ASCII码值,值表示对应按键是否按下 bool keyStates[256] = {false}; void updateKeyStates() { // 先重置所有按键状态 memset(keyStates, 0, sizeof(keyStates)); struct termios oldt, newt; int oldFcntl = fcntl(STDIN_FILENO, F_GETFL); // 修改终端模式:关闭规范模式、回显,设置非阻塞输入 tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); fcntl(STDIN_FILENO, F_SETFL, oldFcntl | O_NONBLOCK); char ch; // 读取输入缓冲区中所有可用字符,更新按键状态 while (read(STDIN_FILENO, &ch, 1) > 0) { keyStates[(unsigned char)ch] = true; } // 恢复终端原设置,避免影响后续终端操作 tcsetattr(STDIN_FILENO, TCSANOW, &oldt); fcntl(STDIN_FILENO, F_SETFL, oldFcntl); } int main() { cout << "Press 'b', 'n', or both together. Press 'q' to quit." << endl; while (true) { updateKeyStates(); // 获取目标按键的状态 bool bPressed = keyStates['b']; bool nPressed = keyStates['n']; bool qPressed = keyStates['q']; if (qPressed) { cout << "Exiting..." << endl; break; } // 判断按键组合并输出 if (bPressed && nPressed) { cout << "'b' and 'n' are pressed together." << endl; } else if (bPressed) { cout << "'b' is pressed alone." << endl; } else if (nPressed) { cout << "'n' is pressed alone." << endl; } // 短暂休眠,避免输出刷屏 usleep(100000); // 100ms } return 0; }
关键改动说明
- 非阻塞输入:通过
fcntl设置O_NONBLOCK标志,让read操作无需等待输入,立即返回缓冲区中所有可用字符,避免程序卡顿。 - 按键状态维护:用
bool数组记录每个ASCII字符的按下状态,每次轮询先重置状态,再读取所有输入字符,确保状态准确反映当前按键组合。 - 终端状态恢复:每次读取完成后恢复终端原始模式,防止终端后续操作异常。
- 频率控制:添加
usleep降低循环频率,避免输出过于频繁。
内容的提问来源于stack exchange,提问作者Tom McLean
相关产品推荐
相关产品推荐

