1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| #include <sys/time.h> #include <stdio.h> #include <termios.h>
/* The original and new terminal attributes */ static struct termios Savedtty, Rawtty; // 设置终端相关属性 static void initKeyboard() { tcgetattr(0,&Savedtty); Rawtty = Savedtty; Rawtty.c_lflag &= ~ICANON; // 设置不以规范模式工作,读请求直接从队列读取字符,至少接到MIN字节或者两个字节之间超时值TIME到期时,read才返回 Rawtty.c_lflag &= ~ECHO; // 关闭输入字符回显到终端设备 // Rawtty.c_lflag &= ~ISIG; // 判断输入字符是否要产生终端信号的特殊字符 Rawtty.c_cc[VMIN] = 1; // 至少接到MIN字节 Rawtty.c_cc[VTIME] = 0; // 两个字节之间超时值TIME tcsetattr(0, TCSANOW, &Rawtty); } // 恢复终端属性 static void closeKeyboard() { tcsetattr(0, TCSANOW, &Savedtty); } // 读取字符 static int chin (int ech, char *buf, unsigned cnt) { int rc; fflush(stdout); if (!ech) rc = read(STDIN_FILENO, buf, cnt); else { tcsetattr(STDIN_FILENO, TCSAFLUSH, &Savedtty); rc = read(STDIN_FILENO, buf, cnt); tcsetattr(STDIN_FILENO, TCSAFLUSH, &Rawtty); } // may be the beginning of a lengthy escape sequence tcflush(STDIN_FILENO, TCIFLUSH); return rc; // note: we do NOT produce a vaid 'string' }
// 判断读取字符的有效性 static char kbhit(){ long file_flags; int rc; char c; fd_set fs; FD_ZERO(&fs); FD_SET(STDIN_FILENO, &fs); file_flags = fcntl(STDIN_FILENO, F_GETFL); if(file_flags==-1) file_flags=0;
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK|file_flags);
// check 1st, in case tv zeroed (by sig handler) before it got set rc = chin(0, &c, 1); if (rc <= 0) { // EOF is pretty much a "can't happen" except for a kernel bug. // We should quickly die via SIGHUP, and thus not spin here. // if (rc == 0) end_pgm(0); /* EOF from terminal */ fcntl(STDIN_FILENO, F_SETFL, file_flags); select(1, &fs, NULL, NULL, NULL); fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK|file_flags); }
if (chin(0, &c, 1) > 0) { fcntl(STDIN_FILENO, F_SETFL, file_flags); return c; } else { fcntl(STDIN_FILENO, F_SETFL, file_flags); } kbhit(); }
## use initKeyboard(); while(true){ char input = kbhit(); if( input == 'q'){ // do something break; } } closeKeyboard();
|