当我按下一个函数或箭头键时,为什么getch会返回三个值?

问题描述 投票:1回答:1

我有一个函数getch(),其工作方式与Unix(Mac OSX?)getchar()或Windows _getch()的工作方式大致相同,只是它不会等待用户在返回值之前按Enter键。我想使用它,因为它避免了必须使用system()来实时输入。 (我必须做一些类似系统(“stty raw”)的事情,用上面提到的函数来做相同的事情,无论出于什么原因,stty raw真的搞砸了我的终端的缩进。)这是代码:

#include <termios.h>
char getch() { 
    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() {
    //std::thread InputThread(GetInput);
    int c = 0;
    while(c != 127) { // Delete key is 127
        c = getch();
        std::cout << "Input: " << c << "\n" << endl;
    }
    std::cout << "Broke!" << endl;
    std::this_thread::sleep_for(std::chrono::seconds(3));
    Quit();
    //InputThread.detach();
    return 0;
}

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

Input: 27
Input: 91
Input: 65

功能键和其他箭头键的输出看起来相似。 (我会注意到,如果我使用getchar(),也会发生这种情况)

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

任何帮助深表感谢。我的平台是Mac OSX,如果它是相关的。

c++ input
1个回答
1
投票

你正在读输入一个字符,一次一个字节;然而,按下单个键可能不一定产生一个字符。按下时,向上光标键生成三个字符ESC [ A,这是光标向上键in the ANSI/VT100 series of terminal emulators的常见映射。

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

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

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

在自己阅读终端时,由您完成所有这些工作。没有别的办法可以帮到你。

© www.soinside.com 2019 - 2024. All rights reserved.