c++ - 为什么按功能键或箭头键时 getch 会返回三个值?

标签 c++ input

我正在尝试编写一个程序,该程序将在用户按下 F1 键时退出。我正在使用自定义函数 myGetch() 从终端获取用户输入。它只是直接从终端获取用户输入,而无需用户按回车键。

我制作了一个小程序来打印出键码,目的是找到 F1 输出的键码,这样我就可以使用该键码而不是“127”作为“删除”键来退出程序。

#include <termios.h>
char myGetch() { 
    char buf = 0;
    struct termios old = {0};
    if (tcgetattr(0, &old) < 0)
        perror("tcsetattr()");
    old.c_lflag &= ~ICANON;
    old.c_lflag &= ~ECHO;
    old.c_cc[VMIN] = 1;
    old.c_cc[VTIME] = 0;
    if (tcsetattr(0, TCSANOW, &old) < 0)
        perror("tcsetattr ICANON");
    if (read(0, &buf, 1) < 0)
        perror ("read()");
    old.c_lflag |= ICANON;
    old.c_lflag |= ECHO;
    if (tcsetattr(0, TCSADRAIN, &old) < 0)
        perror ("tcsetattr ~ICANON");
    return (buf);
}


int main() {
    int c = 0;
    while(c != 127) { // Delete key is 127
        c = myGetch();
        std::cout << "Input: " << c << "\n" << endl;
    }
    std::cout << "User pressed delete!" << endl;
    std::this_thread::sleep_for(std::chrono::seconds(3));
    Quit();
    return 0;
}

它的工作方式如您所料。您输入一个 key ,它会打印回给您。如果按删除,程序退出。然而,奇怪的是,如果你按下向上箭头,你会得到如下所示的输出:

Input: 27
Input: 91
Input: 65

功能键和其他箭头键的输出看起来很相似。

std::cout 只被调用一次。那为什么要打印三次呢?我希望我的程序检测到用户按下 F1,然后退出。但如果我的程序以这种方式运行,我不知道该怎么做。

非常感谢任何帮助。如果相关的话,我的平台是 Mac OSX。

最佳答案

您正在读取一个字符,一次一个字节;但是,按一个键不一定会生成一个字符。光标向上键在按下时生成三个字符,ESC [ A,这是光标向上键的常见映射 in the ANSI/VT100 series of terminal emulators .

即使是字母本身也会在使用非英语键盘映射时生成多个字符。例如,在西里尔键盘上按西里尔字母“а”会读出两个字符:208、176。

请注意,“ESC”键本身读取单个 ESC 字符。读取 ESC 后,没有任何迹象表明这是一个独立的“Esc”按键,还是代表特殊键的许多可能的多字符序列中的第一个。

终端库,如 curses 通常采用在从终端读取 ESC 后开始短暂超时的方法。如果没有更多的字符到达,他们就认为 ESC 是自己按下的。如果立即读取更多字符,它们将尝试查找读取的字符序列代表的特殊键。

当您自己阅读终端时,所有这些工作都由您来完成。没有其他东西可以为您完成这项工作。

关于c++ - 为什么按功能键或箭头键时 getch 会返回三个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52213976/

相关文章:

c++ - GCC 使用 jsoncpp 推断传值复制赋值

C++:新手的仿函数和 std::function

C++ 从二进制文件中读回 "incorrect"值?

c - 从用户获取字符串,然后将其从屏幕上删除

php - 在 php 中上传 docx、zip、rar、pdf、ppt

javascript - 如何防止移动键盘覆盖html输入

c++ - C++ 中的名称和类型

c++ - 将 vector 中的数字放到 vector<vector>> 中,两个数字的差值为 1

c++ - 绝对整数值比较和平方值比较。是等价的吗?

html - 当不透明度为零时,如何隐藏 HTML 文本输入中的插入符号? (IE)