类 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 和 凡人只做一事 两位作者。

posted @   green-cnblogs  阅读(158)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
点击右上角即可分享
微信分享提示