【问题标题】:C++ noncanonical terminal read() specific keysC++ 非规范终端 read() 特定键
【发布时间】:2022-01-28 15:25:40
【问题描述】:

我有以下代码:

int setmode(int vtime, int vmin, int echo, int sigint)
{
    termios attr;
    tcgetattr(STDIN_FILENO, &attr);

    attr.c_lflag &= ~ICANON;
    if (echo)
        attr.c_lflag |= ECHO;
    else
        attr.c_lflag &= ~ECHO;
    if (sigint)
        attr.c_lflag |= ISIG;
    else
        attr.c_lflag &= ~ISIG;
    attr.c_cc[VMIN] = vmin;
    attr.c_cc[VTIME] = vtime;
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &attr);
    return 0;
}

int main()
{
    setmode(0, 1, false, true);
    while (true)
    {
        char c;
        read(0, &c, 1);
        cout << c;
        fflush(stdout);
    }
    return 0;
}

这会正确地回显键(在删除 cout &lt;&lt; c; 时会停止回显,因此我认为读取工作正确且 c 包含正确的字符)。现在我想测试是否按下了某些特定的键,例如箭头、回车或退格键。对于键,我尝试过类似

if (c == '\[A') cout &lt;&lt; "smth"; 而不是cout &lt;&lt; c;,但这什么也没打印。同样从 infocmp 我发现箭头键具有以下 esc 序列:

kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA 并对其进行了测试,但均无效。那么在这段代码中,我如何测试箭头、回车、退格、一些 F 键? 另外,是否可以将 setmode 的 if-else 语句简化为单个位表达式赋值?

【问题讨论】:

    标签: c++ linux terminal escaping


    【解决方案1】:

    好的,所以我通过将 c 转换为 int 找到了解决方案。

    1. 输入 - 10
    2. 退格键 - 127
    3. 箭头是 3 个字符的序列,第一个是 27 和 91,第三个显示确切的字符
    4. 功能键是 5 个字符的序列,第一个是 27 91 49,第 4 个是键,第 5 个是我的两个 F 键的 126(但仍需要从缓冲区读取)。

    【讨论】:

      猜你喜欢
      • 2010-09-26
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 2020-12-24
      • 1970-01-01
      • 1970-01-01
      • 2017-04-10
      相关资源
      最近更新 更多