1.使用非阻塞方式獲取標准輸入


//首先,我們先來看總的main函數框架
1
int main() 2 { 3 char c; 4 int i=0; 5 6 nonblock(NB_ENABLE); 7 while(!i) 8 { 9 usleep(1); 10 i=kbhit(); 11 if (i!=0) 12 { 13 c=fgetc(stdin); 14 if (c=='q') 15 i=1; 16 else 17 i=0; 18 } 19 20 fprintf(stderr,"%d ",i); 21 } 22 printf("\n you hit %c. \n",c); 23 nonblock(NB_DISABLE); 24 25 return 0; 26 }

nonblock函數的原型如下:

 1 void nonblock(int state)
 2 {
 3     struct termios ttystate;
 4  
 5     //get the terminal state
 6     tcgetattr(STDIN_FILENO, &ttystate);
 7  
 8     if (state==NB_ENABLE)
 9     {
10         //turn off canonical mode
11         ttystate.c_lflag &= ~ICANON;
12         //minimum of number input read.
13         ttystate.c_cc[VMIN] = 1;//有一個數據時就立刻返回
14     }
15     else if (state==NB_DISABLE)
16     {
17         //turn on canonical mode
18         ttystate.c_lflag |= ICANON;
19     }
20     //set the terminal attributes.
21     tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
22  
23 }

nonblock函數主要完成以下工作:

a.從標准輸入獲取狀態,存放在ttystate中

b.關閉the canonical mode,通過置0的方式實現。

c.通過ttystate設置標准輸入的狀態。

 

kbhit函數的原型如下:

 1 int kbhit()
 2 {
 3     struct timeval tv;
 4     fd_set fds;
 5     tv.tv_sec = 0;
 6     tv.tv_usec = 0;
 7     FD_ZERO(&fds);
 8     FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
 9     select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
10     return FD_ISSET(STDIN_FILENO, &fds);
11 }

該函數主要通過timeval和select函數來實現的。select函數主要用於一些某些需要加工的多功能的I/O口中。如果不會使用select函數,可以查看《Unix高級編程》或者參考select函數的用法

kbhit函數主要完成的工作如下:

a.設置tv.tv_sec和tv.tv_usec為0,不等待,一直查詢端口。

b.FD的設置

c.調用select函數,Seems we are only interested in input, so we place out fd set at second parameter of select(), the 3rd is for output and 4th is for exception.

注意:如果user input被觸發,FD_ISSET將返回非0值,否則返回0;所以應該加如下的返回值判斷。

1 while(!kbhit())
2 {
3       //do certain operation..
4 }
5 //user hits enter.

Due to the canonical mode of your terminal, you need to hit enter to confirm your user input. Canonical mode means it always wait for enter to confirms the user input.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM