Today, we see a shell source code, which can be used to receive characters without entering the carriage return. In this source code, it is used to receive up/down keys in shell and execute historical commands.
Original code:
/* How to read a character without pressing enter, this program can be used to view the character encoding of the keyboard */<br/>/* <br/> take the "up arrow key" as an example. The three characters are 27 <ESC>, 79 <o>, and 65 <A>. A> <br/> the read () function in the above getch () function reads only one character from the standard input once. <br/> therefore, in getch () when one character is returned and then called again, the buffer of the standard input has two characters. <br/> therefore, read () the function does not block (although we didn't press any key at this time), but reads 2nd characters, <br/> Returns, and then continues to read 3rd characters. <Br/> therefore, if you press a direction key, the getch () function is actually called three times. <Br/> */</P> <p> # include <stdio. h> <br/> # include <termio. h> <br/> # include <stdlib. h> </P> <p> static struct termios tty; <br/> void set_key (); <br/> void reset_key (); <br/> char getch (); </P> <p> main () <br/>{< br/> char a; <br/> set_key (); <br/> while (1) <br/> {<br/> A = getch (); <br/> printf ("% d % C/N",, a); <br/> if (a = '0') <br/> break; <br/>}< br/> reset_key (); <br/>}< br/> void set_key () <br/> {<br/> struct t Ermios new_tty; <br/> tcgetattr (0, & TTY); <br/> new_tty = tty; <br/> new_tty.c_lflag & = ~ (Icanon | echo | isig); <br/> new_tty.c_cc [vtime] = 0; <br/> new_tty.c_cc [Vmin] = 1; <br/> tcsetattr (0, tcsanow, & new_tty); <br/> return; <br/>}< br/> void reset_key () <br/>{< br/> tcsetattr (0, tcsanow, & TTY); <br/> return; <br/>}< br/> char getch () <br/>{< br/> int I; <br/> char ch; <br/> switch (I = read (0, & Ch, 1) <br/>{< br/> case-1: <br/> printf ("error/N"); <br/> exit (3); <br/> case 0: <br/> printf ("error0/N"); <br/> exit (4); <br/>}< br/> return (CH ); <br/>}</P> <p>
Upgrade:
/* For Ultimate Edition, you do not need to enter a carriage return to automatically obtain characters. The function of this code blocks the input of other buttons and only receives ESC, <br/> press enter and four direction keys, the user input is displayed. If you press the ESC key, the program ends. */</P> <p> # include <stdio. h> <br/> # include <termio. h> <br/> static struct termios tty; <br/> Enum key {none, keyescclick, keyenterclick, <br/> keyupclick, keydownclick, <br/> keyleftclick, keyrightclick }; <br/> void set_key (); <br/> void reset_key (); <br/> Enum key getch (); </P> <p> int main (INT argc, char * argv []) <br/>{< br/> Enum key a; <br/> set_key (); <br/> while (1) <br/>{< br/> A = getch (); <br/> Switch (A) <br/>{< br/> case keyescclick: <br/> printf ("ESC/N"); <br/> reset_key (); <br/> return 0; <br/> case keyenterclick: <br/> printf ("Enter/N"); <br/> break; <br/> case keyupclick: <br/> printf ("up/N"); <br/> break; <br/> case keydownclick: <br/> printf ("down/N "); <br/> break; <br/> case keyleftclick: <br/> printf ("Left/N"); <br/> break; <br/> case keyrightclick: <br/> printf ("right/N"); <br/> bre AK; <br/> default: <br/> break; <br/>}< br/> <br/> reset_key (); <br/> return 0; <br/>}< br/> void set_key () <br/>{< br/> struct termios new_tty; <br/> tcgetattr (0, & TTY ); <br/> new_tty = tty; <br/> new_tty.c_lflag & = ~ (Icanon | echo | isig); <br/> new_tty.c_cc [vtime] = 0; <br/> new_tty.c_cc [Vmin] = 1; <br/> tcsetattr (0, tcsanow, & new_tty); <br/> return; <br/>}< br/> void reset_key () <br/>{< br/> tcsetattr (0, tcsanow, & TTY); <br/> return; <br/>}< br/>/* <br/> modified the getch function. Due to the special character encoding of the up and down arrow keys, therefore, in read, if only one character is read at a time, it is a common character. <br/> if it is three characters, it is the direction key, by judging the content of the last character, you can determine which one is in the direction key. <Br/> */<br/> Enum key getch () <br/> {<br/> int I; <br/> char ch [3]; <br/> while (I = read (0, CH, 3 ))! =-1) <br/>{< br/> printf ("Get char num: % d/N", I); <br/> switch (I) <br/>{< br/> case 1: <br/> switch (CH [0]) <br/>{< br/> case 0x1b: <br/> return keyescclick; <br/> case 0x0a: <br/> return keyenterclick; <br/>}< br/> break; <br/> case 3: <br/> switch (CH [2]) <br/>{< br/> case 'A': <br/> return keyupclick; <br/> case 'B': <br/> return keydownclick; <br/> case 'C': <br/> return keyrightclick; <br/> case 'D': <br/> return keyleftclick; <br/>}< br/> return none; <br/>}< br/>