The getch () function source code found on the internet is as follows:
#include <termios.h>#include <unistd.h>#include <stdio.h>int getch(void) {struct termios tm, tm_old;int fd = STDIN_FILENO, c;if(tcgetattr(fd, &tm) < 0)return -1;tm_old = tm;cfmakeraw(&tm);if(tcsetattr(fd, TCSANOW, &tm) < 0)return -1;c = fgetc(stdin);if(tcsetattr(fd, TCSANOW, &tm_old) < 0)return -1;return c;}
After testing, the direction keys cannot be used normally in Linux, and other keys can be recognized normally. To solve this problem, I used the simulated kbhit function to check whether there are multiple key values. If yes, accumulate key values as follows:
Int set_raw (INT t) {static struct termio tty; struct termio TMP; If (t) {IOCTL (0, tcgeta, & TTY); TMP = tty; TMP. c_lflag & = ~ (Icanon | echoprt); TMP. c_cc [Vmin] = 1; TMP. c_cc [vtime] = 0; IOCTL (0, tcseta, & TMP);} else {TTY. c_lflag & = ~ (Icanon | echo); IOCTL (0, tcseta, & TTY) ;}return 0 ;}int kbhit (void) {struct termios oldt, Newt; int ch; int oldf; set_raw (3); tcgetattr (stdin_fileno, & oldt); Newt = oldt; newt. c_lflag & = ~ (Icanon | echo); tcsetattr (stdin_fileno, tcsanow, & Newt); oldf = fcntl (records, f_getfl, 0); fcntl (records, f_setfl, oldf | o_nonblock ); ch = getchar (); tcsetattr (stdin_fileno, tcsanow, & oldt); fcntl (stdin_fileno, f_setfl, oldf); If (Ch! = EOF) {ungetc (CH, stdin); return 1 ;}set_raw (0); Return 0 ;}int getch (void) {struct termios TM, tm_old; int FD = stdin_fileno, C; input = 0; If (tcgetattr (FD, & TM) <0) Return-1; tm_old = TM; TM. c_lflag & = ~ (Icanon | echo | isig); If (tcsetattr (FD, tcsanow, & TM) <0) Return-1; C = fgetc (stdin); If (kbhit ()) {/* if there is another key value */C + = getch ();} If (tcsetattr (FD, tcsanow, & tm_old) <0) Return-1; if (C = 3) Exit (1);/* if it is Ctrl + C, force terminate the Program */return C ;}
The code used in the lcui project is as follows:
Static struct termios TM, tm_old; static int FD = stdin_fileno; int set_raw (INT t) {If (T> 0) {If (tcgetattr (FD, & TM) <0) return-1; tm_old = TM; TM. c_lflag & = ~ (Icanon | echo); TM. c_cc [Vmin] = 1; TM. c_cc [vtime] = 0; If (tcsetattr (FD, tcsanow, & TM) <0) Return-1; printf ("\ 033 [? 25l ");/* Hide the cursor */} else {printf (" \ e [? 25 H ");/* display cursor */If (tcsetattr (FD, tcsanow, & tm_old) <0) Return-1;} return 0;} int check_key (void) {struct termios oldt, Newt; int ch; int oldf; tcgetattr (stdin_fileno, & oldt); Newt = oldt; newt. c_lflag & = ~ (Icanon | echo); tcsetattr (stdin_fileno, tcsanow, & Newt); oldf = fcntl (records, f_getfl, 0); fcntl (records, f_setfl, oldf | o_nonblock ); ch = getchar (); tcsetattr (stdin_fileno, tcsanow, & oldt); fcntl (stdin_fileno, f_setfl, oldf); If (Ch! = EOF) {ungetc (CH, stdin); return 1;} return 0;} static int input, Count = 0; int get_key (void) {++ count; int K, c; k = fgetc (stdin); input + = K; If (check_key () {get_key () ;}c = input; -- count; If (COUNT = 0) input = 0; If (C = 3) Exit (1); Return C ;}
The set_raw () function is used to initialize and restore terminal properties. If the parameter T is greater than 0, it is initialized. Otherwise, terminal properties are restored.
The check_key () function is the same as the kbhit () function to check whether there is a key input.
The get_key () function is used to obtain the characters entered by the key.