2

GitHub

这是我能想到的最好的处理 ncurses 式按键的方法(由于各种原因,我实际上正在编写 ncurses 的替代方案)。

使用此代码构建的示例应用程序建议用户“按 Escape 退出”。事实上,它需要 Escape + Escape 或 Escape + An Arrow Key。我想解决这个问题。

#include <sys/ioctl.h>
#include <termios.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *get_key() {
    char c = getchar();

    switch(c) {
        case 'a': return "a";
        case 'b': return "b";
        case 'c': return "c";

        ...

        case '\x1b':
            c = getchar();
            switch(c) {
                case '[':
                    c = getchar();
                    switch(c) {
                        case 'A': return "up";
                        case 'B': return "down";
                        case 'C': return "right";
                        case 'D': return "left";
                    }
                case '\x1b': return "escape";
            }

        default: return "unknown";
    }
4

3 回答 3

2

步骤 1. 研究。

http://en.wikipedia.org/wiki/Escape_sequence

如果 Esc 键和其他发送转义序列的键都应该对应用程序有意义,那么在使用终端或终端仿真器时就会出现歧义。特别是,当应用程序接收到 ASCII 转义字符时,不清楚该字符是用户按下 Esc 键的结果还是转义序列的初始字符(例如,由箭头键按下产生) . 解决歧义的传统方法是观察另一个字符是否快速跟随转义字符。如果不是,则假定它不是转义序列的一部分。这种启发式在某些情况下可能会失败,但实际上它工作得相当好,尤其是在现代通信速度更快的情况下。

第 2 步。弄清楚如何查看在您的操作系统的输入缓冲区中是否有另一个字符在等待。如果缓冲区中已经有一个字符;这是一个转义序列。如果输入缓冲区为空,则为转义。

由于您没有提及您的操作系统,因此尚不清楚如何做到这一点。

Windows:与 sys/select.h 和 termios.h 中定义的功能等效的 Windows 是什么?

Linux: http: //linux.die.net/man/3/termios

于 2011-07-14T10:22:42.947 回答
0

VMIN与其依赖/相当脆弱的计时机制VTIME,您可能更愿意将计时逻辑上移到纯用户区。我写了一个库来处理这个和其他一些情况:

http://www.leonerd.org.uk/code/libtermkey/

As well as distinguishing Escape from arrow keys, it can also handle things like modified arrow keys and modified Unicode that modern terminals are starting to use, supports both blocking and non-blocking uses, and many other things. In fact your get_key() function could be easily performed by termkey_waitkey() to obtain a keypress followed by termkey_strfkey() to format it into a string buffer.

于 2012-04-05T13:16:08.227 回答
-2

缓冲区和一些位选项很好地完成了这项工作。

GitHub

于 2011-07-19T00:53:20.010 回答