Linux下的getch()函数的改进版
Linux下的getch()函数的改进版
getch()函数源码如下:[cpp]
- #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;
- }
经测试,在Linux下无法正常使用方向键,其余键能正常识别,为了解决这问题,我利用了模拟实现的kbhit函数检测是否有多个键值,有的话,累加键值,具体如下:
[cpp]- 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(STDIN_FILENO, F_GETFL, 0);
- fcntl(STDIN_FILENO, 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;
- }
- static int input;
- 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;
- int k;
- input = fgetc(stdin);
- k = input;
- if(kbhit()){ /* 如果还有下一个键值 */
- input += getch();
- }
- if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;
- c = input;
- if(c == 3) exit(1); /*如果是Ctrl+C组合键,就强制终止程序*/
- return c;
- }
本函数的代码仅在诺亚舟NP1500学习机里测试通过,并不保证在其它平台上也能正常执行。
评论暂时关闭