Linux下无需按下回车(无阻塞)读取输入键值

linux常用输入函数scanf和fgets通常都是阻塞式的:

  1、如果用户没有输入,则程序会阻塞等待用户输入输入内容后,且需要用户点回车键才能完成读取键盘输入。

  2、用户输入的信息,会在屏幕上显示出来。 

 

一、以下代码实现了:

  1、用户没有输入,则在设定时间过后,程序会继续运行下去

  2、用户输入信息不会在屏幕上显示出来

  3、程序能够不等待回车,直接响应键盘输入

  4、用到了system函数,会启动子进程(缺点)。

  5、此种方法是使用stty命令,设置终端输入为禁止回显并忽略回车符来实现的。

 1 #include <stdio.h>                                 
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4  
 5 #define TTY_PATH            "/dev/tty"
 6 #define STTY_US             "stty raw -echo -F "
 7 #define STTY_DEF            "stty -raw echo -F "
 8 
 9 #define UNUSED_PARAMTER(X)    (void)(X)
10  
11 static char get_char( void )
12 {
13     fd_set rfds;
14     struct timeval tv;
15     char input_char = 0;
16 
17     FD_ZERO(&rfds);
18     FD_SET(0, &rfds);
19 
20     /**
21      * Set wait time
22      */
23     //tv.tv_sec = 0;    //seconds
24     //tv.tv_usec = 500;  //microseconds
25 
26     /*Check for keyboard input.*/
27     if (select(1, &rfds, NULL, NULL, &tv) > 0)
28         input_char = getchar();
29 
30     return input_char;
31 }
32  
33 char nonblocking_input( void )
34 {
35     char input_char;
36     
37     system(STTY_US TTY_PATH);     //Prohibit echoing,ignoring carriage returns
38 
39     usleep(100);
40     input_char = get_char();
41 
42     system(STTY_DEF TTY_PATH);    //Turn on echo and don't ignore carriage return
43 
44     return input_char;
45 }
46  
47 int main(int argc, char **argv)
48 {
49     UNUSED_PARAMTER(argc);
50     UNUSED_PARAMTER(argv);
51 
52     char input_char;
53 
54     input_char = nonblocking_input();
55 
56    printf("\n\tYour input is %c!\n", input_char);
57    printf("\nApplication finish.\n\n");
58 
59    return 0;
60 }    
nonblocking.c

二、另外一种方法,相对于第一种方法,改进点主要有:

  1、使用tcgetattr函数和tcsetattr函数代替system函数,减少子进程启动数量。

  2、此种实现是通过termios来实现的,termios的实现中,有大量的参数设置,还有伪终端的说法。

代码如下:

 1 #include <stdio.h>
 2 #include <fcntl.h>
 3 #include <termios.h>
 4 #include <unistd.h>
 5 
 6 #define UNUSED_PARAMTER(X)    (void)(X)
 7 
 8 char nonblocking_input(void)
 9 {
10     char input_ch;
11     struct termios newt, oldt;
12     
13     int tty = open("/dev/tty", O_RDONLY);    //Open control terminal
14     
15     tcgetattr(tty, &oldt);            //Get terminal properties
16     newt = oldt;
17     
18     //Set characters are not buffered(~ICANON) and do not echo(~ECHO).
19     //You can also choose only one of them.
20     newt.c_lflag &= ~( ICANON | ECHO );
21     tcsetattr(tty, TCSANOW, &newt);
22     
23     read(tty, &input_ch, 1);
24     tcsetattr(tty, TCSANOW, &oldt);        //Restore terminal properties
25 
26     return input_ch;
27 }
28 
29 int main(int argc, char **argv)
30 {
31     UNUSED_PARAMTER(argc);
32     UNUSED_PARAMTER(argv);
33 
34     char input_char;
35 
36     input_char = nonblocking_input();
37 
38     printf("\n\tYour input is %c!\n", input_char);
39     printf("\nApplication finish.\n\n");
40     
41     return 0;
42 }  
nonblocking_inout.c

 

posted @ 2018-03-18 22:43  zhengzhuo  阅读(2669)  评论(0编辑  收藏  举报