类 Unix 环境下无需等待回车即可获取来自键盘输入
本文描述了在类 Unix 操作系统中,无需等待回车即可获取来自键盘输入的办法,并加以了验证。
◆ 目的
在类 Unix 操作系统(如 Linux、macOS)中,如何能实现无需等待回车即可获取来自键盘输入?
◆ 解法
通过 termios 程序库中与终端关联的 termios 结构和 tcgetattr、tcsetattr 函数,改变终端编辑模式为非规范输入且不回显,即可实现“无需等待回车即可获取来自键盘的输入”的功能。
◆ 示例
以下代码片段展示了此实现方案,(how_to_get_input_without_enter.cpp)
#include <stdio.h>
#include <termios.h> // #1
int hit_key() {
termios oldattr;
tcgetattr(0, &oldattr); // #2
termios newattr = oldattr; // #3
newattr.c_lflag &= ~(ICANON | ECHO); // #4
tcsetattr(0, TCSANOW, &newattr);
int code = getchar();
tcsetattr(0, TCSANOW, &oldattr); // #5
return code;
}
首先需要包含 termios.h 程序库(#1),该文件定义了与终端关联的 termios 结构和 tcgetattr、tcsetattr 函数。使用 tcgetattr 函数获取当前终端的属性,并保存在 termios 结构的变量中(#2)。为了能将终端属性恢复成原有值,先用原有终端属性复制出一份临时属性(#3)。改变终端编辑模式的关键,在于 termios.c_lflag 字段。将临时属性的 c_lflag 字段改变为非规范输入且不回显(#4),并设置终端属性为新值。应用结束后,将终端属性恢复成原有值(#5)。
◆ 验证
在命令行中编译代码(-std=c++11),运行可执行文件并检查输出结果(要输入 ASCII 中的控制字符,可参考 命令行中输入 ASCII 字符 )。以下是输出结果的部分内容,
$ ./a.out
Please hit a key (Ctrl-C to quit).
......
Your input is A, its ASCII code is 65.
Your input is [, its ASCII code is 91.
Your input is B, its ASCII code is 66.
Your input is 5, its ASCII code is 53.
Your input is ~, its ASCII code is 126.
......
◆ 最后
完整的代码请参考 [gitee] cnblogs/15691156 。
写作过程中,笔者参考了 Linux下C++/C终端获取键盘事件/termios结构详细解释 和 LINUX 使用tcgetattr与tcsetattr函数控制终端。致 Liuqz2009 和 凡人只做一事 两位作者。
受限于作者的水平,读者如发现有任何错误或有疑问之处,请追加评论或发邮件联系 green-pi@qq.com。作者将在收到意见后的第一时间里予以回复。 本文来自博客园,作者:green-cnblogs,转载请注明原文链接:https://www.cnblogs.com/green-cnblogs/p/15691156.html 谢谢!