Linux环境下C++实现键盘按键按下检测功能咨询
Linux 环境 C++ 非阻塞按键检测实现
Linux 终端默认采用行缓冲模式,只有按下回车后输入才会提交给程序,要实现循环内实时检测按键状态,需要修改终端属性为非规范模式,同时配置非阻塞 IO 避免循环卡住。
完整实现代码
#include <iostream> #include <termios.h> #include <unistd.h> #include <fcntl.h> #include <string> #include <map> // 按键名与ASCII码映射,可按需扩展 std::map<std::string, int> key_map = { {"space", 32}, {"enter", 10}, {"esc", 27}, {"backspace", 127}, {"tab", 9}, {"a", 97}, {"b",98}, {"c",99}, {"d",100}, {"e",101}, {"f",102}, {"g",103}, {"h",104}, {"i",105}, {"j",106}, {"k",107}, {"l",108}, {"m",109}, {"n",110}, {"o",111}, {"p",112}, {"q",113}, {"r",114}, {"s",115}, {"t",116}, {"u",117}, {"v",118}, {"w",119}, {"x",120}, {"y",121}, {"z",122}, {"0",48}, {"1",49}, {"2",50}, {"3",51}, {"4",52}, {"5",53}, {"6",54}, {"7",55}, {"8",56}, {"9",57} }; struct termios orig_termios; // 程序退出时恢复终端默认属性 void reset_terminal() { tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios); } bool IsKeyPressed(const std::string& key_name) { static bool init = false; if (!init) { // 保存原有终端属性 tcgetattr(STDIN_FILENO, &orig_termios); atexit(reset_terminal); termios new_termios = orig_termios; // 关闭规范模式、回显,不需要按回车即可获取输入,输入不显示在终端 new_termios.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &new_termios); // 设置标准输入为非阻塞模式 int flags = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); init = true; } // 检查目标按键是否在映射表中 if (key_map.find(key_name) == key_map.end()) { return false; } int target_key = key_map[key_name]; int ch; bool pressed = false; // 读取缓冲区所有字符,判断是否有目标按键 while ((ch = getchar()) != EOF) { if (ch == target_key) { pressed = true; } } return pressed; } int main(int argc, char** argv){ std::cout << "Press the spacebar to exit loop" << std::endl; while (true){ if (IsKeyPressed("space")){ break; } // 这里可添加其他循环逻辑 usleep(1000); // 避免空转占用过高CPU } std::cout << "Loop exited successfully" << std::endl; return 0; }
注意事项
- 本实现仅检测当前终端聚焦时的输入,不是全局键盘监听,仅适用于终端程序场景
- 编译运行不需要依赖额外第三方库,直接使用
g++ key_detect.cpp -o key_detect && ./key_detect即可运行 - 如果程序异常退出导致终端输入不显示,在终端执行
reset命令即可恢复默认终端配置
内容的提问来源于stack exchange,提问作者Samuel Oliveira
相关产品推荐
相关产品推荐

