歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux下的getch()函數的改進版

getch()函數源碼如下:

[cpp]
  1. #include <termios.h>   
  2. #include <unistd.h>   
  3. #include <stdio.h>   
  4. int getch(void) {  
  5.     struct termios tm, tm_old;  
  6.     int fd = STDIN_FILENO, c;  
  7.     if(tcgetattr(fd, &tm) < 0)  
  8.     return -1;  
  9.     tm_old = tm;  
  10.     cfmakeraw(&tm);  
  11.     if(tcsetattr(fd, TCSANOW, &tm) < 0)  
  12.     return -1;  
  13.     c = fgetc(stdin);  
  14.     if(tcsetattr(fd, TCSANOW, &tm_old) < 0)  
  15.     return -1;  
  16.     return c;  
  17. }  

經測試,在Linux下無法正常使用方向鍵,其余鍵能正常識別,為了解決這問題,我利用了模擬實現的kbhit函數檢測是否有多個鍵值,有的話,累加鍵值,具體如下:

[cpp]
  1. int set_raw(int t)  
  2. {  
  3.     static struct termio tty ;  
  4.     struct termio tmp ;  
  5.   
  6.     if (t) {  
  7.         ioctl(0,TCGETA,&tty) ;  
  8.         tmp = tty ;  
  9.         tmp.c_lflag &= ~(ICANON|ECHOPRT);  
  10.         tmp.c_cc[VMIN] = 1 ;  
  11.         tmp.c_cc[VTIME] = 0 ;  
  12.         ioctl(0,TCSETA,&tmp) ;  
  13.     }  
  14.     else {  
  15.         tty.c_lflag &= ~(ICANON|ECHO);  
  16.         ioctl(0,TCSETA,&tty);  
  17.     }  
  18.     return 0;  
  19. }  
  20. int kbhit(void)    
  21. {    
  22.     struct termios oldt, newt;    
  23.     int ch;    
  24.     int oldf;    
  25.     set_raw(3);  
  26.     tcgetattr(STDIN_FILENO, &oldt);    
  27.     newt = oldt;    
  28.     newt.c_lflag &= ~(ICANON | ECHO);    
  29.     tcsetattr(STDIN_FILENO, TCSANOW, &newt);    
  30.     oldf = fcntl(STDIN_FILENO, F_GETFL, 0);    
  31.     fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);    
  32.     ch = getchar();    
  33.     tcsetattr(STDIN_FILENO, TCSANOW, &oldt);    
  34.     fcntl(STDIN_FILENO, F_SETFL, oldf);    
  35.     if(ch != EOF)    
  36.     {    
  37.         ungetc(ch, stdin);    
  38.         return 1;  
  39.     }  
  40.     set_raw(0);  
  41.     return 0;    
  42. }   
  43.   
  44.   
  45.   
  46. static int input;  
  47.   
  48.   
  49. int getch(void)  
  50. {   
  51.     struct termios tm, tm_old;   
  52.     int fd = STDIN_FILENO,c;  
  53.     input = 0;  
  54.     if(tcgetattr(fd, &tm) < 0)   
  55.     return -1;   
  56.   
  57.     tm_old = tm;   
  58.   
  59.     tm.c_lflag &= ~(ICANON|ECHO|ISIG);  
  60.     if(tcsetattr(fd, TCSANOW, &tm) < 0)   
  61.     return -1;   
  62.   
  63.     int k;  
  64.     input = fgetc(stdin);  
  65.     k = input;  
  66.     if(kbhit()){ /* 如果還有下一個鍵值 */  
  67.         input += getch();  
  68.     }  
  69.     if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;  
  70.     c = input;  
  71.     if(c == 3) exit(1); /*如果是Ctrl+C組合鍵,就強制終止程序*/  
  72.     return c;   
  73. }  

本函數的代碼僅在諾亞舟NP1500學習機裡測試通過,並不保證在其它平台上也能正常執行。

Copyright © Linux教程網 All Rights Reserved