【问题标题】:Reading ESC on Linux during unbuffered input in C在 C 中的无缓冲输入期间在 Linux 上读取 ESC
【发布时间】:2013-12-06 16:49:04
【问题描述】:

我为程序编写了一个 getch 函数。我不能使用诅咒,因为它破坏了我已经使用的iostream 的终端。代码:

inline std::string getch() {
    char inp[4];
    system("stty raw");
    inp[0] = std::cin.get();
    if(inp[0] == 27 && (inp[1] = std::cin.get()) != std::char_traits<char>::eof()) {
        std::cin>>inp[2];
        inp[3] = '\0';
    }
    else {
        inp[1] = '\0';
    }
    system("stty cooked echo");
    return std::string(inp);
}

我知道使用termios.h 而不是系统调用会更好。一切正常,除非ESC key。我正在尝试捕获例如"\1B[A" 字符串的箭头。当我检测到ESC 作为第一个字符时,我还阅读了第二个字符以获得完整的密钥代码。 问题是当我按下 ESC 时它不应该发生,因为它的代码是 1B 单独的。 cin.get() 应该在读取期间缓冲区为空时return EOF,但它只是停止。

有没有办法在不使用诅咒的情况下读取linux 上的ESC 键?为什么我的解决方案不起作用?

谢谢

【问题讨论】:

  • 不,使用ncurses 或者readline 库。其他方案都不实用,除非你很了解tty-s ....

标签: c++ linux ansi-escape stty


【解决方案1】:

经过数小时的搜索,我找到了解决方案。我不得不使用 unistd.h 中的读取功能 它使用输入中的字符填充给定大小的数组。当一个键被按下时,缓冲区被所有读取的字符填充(也适用于多个键)。因此,ESC 只需 {27,0,0,...,0} 和箭头 {27,'[','A',0,0,...,0}。 我已经使用 termios.h 重写了我的函数并将其放入库中,因此任何人都可以受益。

代码如下: readkey on github

【讨论】:

  • 很高兴它有效。过去,想要区分按下退出键和按下箭头或数字小键盘键的程序不得不摆弄 termios VTIMEVMIN 值。在十分之几秒内出现的多个字符被认为来自箭头或数字键盘键。
猜你喜欢
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多