I wrote a getch function for program. I couldn't use curses as it breaks the terminal for iostream
I already use. The code:
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.
Is there a way to read ESC
key on linux
without using curses? Why my solution isn't working?
Thanks
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.
Here is the code: readkey on github