在C中的无缓冲输入期间在Linux上读取ESC

时间:2021-06-28 00:06:20

I wrote a getch function for program. I couldn't use curses as it breaks the terminal for iostream I already use. The code:

我为程序编写了一个getch函数。我无法使用curses,因为它打破了我已经使用的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);
}

I know it would be better to use termios.h instead of system calls. Everything works fine except if ESC key. I'm trying to capture arrows which are string of for example "\1B[A". When I detect ESC as first character I also read the second two to get full key code. The problem is that it shouldn't occur when I press ESC as it's code is 1B alone. The cin.get() should return EOF when the buffer is empty during read, but it simply stops.

我知道使用te​​rmios.h而不是系统调用会更好。除ESC键外,一切正常。我正在尝试捕获例如“\ 1B [A”的字符串的箭头。当我将ESC检测为第一个字符时,我还读取了后两个以获取完整的密钥代码。问题是当我按下ESC时它不应该出现,因为它的代码只有1B。当读取期间缓冲区为空时,cin.get()应返回EOF,但它只是停止。

Is there a way to read ESC key on linux without using curses? Why my solution isn't working?

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

Thanks

1 个解决方案

#1


1  

After many hours of searching I found the solution. I had to use read function from unistd.h It fills an array of given size, with characters from the input. When a key is pressed the buffer is filled with all read characters (works also on multiple keys). So an ESC has simply {27,0,0,...,0} and arrow {27,'[','A',0,0,...,0}. I've rewritten my function using termios.h and put in library, so anyone can benefit.

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

Here is the code: readkey on github

这是代码:github上的readkey

#1


1  

After many hours of searching I found the solution. I had to use read function from unistd.h It fills an array of given size, with characters from the input. When a key is pressed the buffer is filled with all read characters (works also on multiple keys). So an ESC has simply {27,0,0,...,0} and arrow {27,'[','A',0,0,...,0}. I've rewritten my function using termios.h and put in library, so anyone can benefit.

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

Here is the code: readkey on github

这是代码:github上的readkey