• 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("
    	Your input is %c!
    ", input_char);
    57    printf("
    Application finish.
    
    ");
    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("
    	Your input is %c!
    ", input_char);
    39     printf("
    Application finish.
    
    ");
    40     
    41     return 0;
    42 }  
    nonblocking_inout.c
  • 相关阅读:
    七牛大数据平台的演进与大数据分析实践--转
    Re:从0开始的微服务架构:(一)重识微服务架构--转
    Re:从 0 开始的微服务架构--(三)微服务架构 API 的开发与治理--转
    Java7里try-with-resources分析--转
    线上服务CPU100%问题快速定位实战--转
    Windows下本机简易监控系统搭建(Telegraf+Influxdb+Grafana)--转
    Scalable, Distributed Systems Using Akka, Spring Boot, DDD, and Java--转
    ES Segment Memory——本质上就是segment中加到内存的FST数据,因此segment越多,该内存越大
    Self Organizing Maps (SOM): 一种基于神经网络的聚类算法
    RBF网络——核心思想:把向量从低维m映射到高维P,低维线性不可分的情况到高维就线性可分了
  • 原文地址:https://www.cnblogs.com/zhengzhuo-272/p/8598069.html
Copyright © 2020-2023  润新知