raw terminal mode - how to take in input?

前端 未结 2 748
甜味超标
甜味超标 2021-01-21 04:55

I have a chat client that takes in input in raw terminal mode, but I don\'t know about handling input in this mode. I need to know 2 things:

  • How can I read the inp
相关标签:
2条回答
  • 2021-01-21 05:04

    I recommend the GNU readline library for this. It takes care of the tedious work of getting lines of input, and allows the user to edit his line with backspace, left and right arrows, etc, and to recall older command using the up arrow and even search for older command using ^R, etc. Readline comes installed with typical unix-like distributions like linux, but if you don't have it, you can find it here

    Edit: Here is a minimal readline example:

    #include <stdio.h>
    #include <readline/readline.h>
    #include <readline/history.h>
    
    int main(int argc, char ** argv)
    {
        while(1)
        {
            char * line = readline("> ");
            if(!line) break;
            if(*line) add_history(line);
            /* Do something with the line here */
        }
    }
    

    Compile with gcc -o test test.c -lreadline -lncurses.

    If you can't use readline, getline is an alternative:

    #include <stdio.h>
    int main()
    {
        char * line = NULL;
        size_t len;
        while(getline(&line, &len, stdin) >= 0)
           printf("I got: %s", line);
    }
    

    If even getline is unacceptable, you can use fgets. It will not dynamically allocate a buffer of suitable size, so too long lines will be truncated. But at least it is standard C:

    #include <stdio.h>
    int main()
    {
        char buf[1000];
        while(fgets(buf, sizeof(buf), stdin)
            printf("I got: %s, line);      
    }
    
    0 讨论(0)
  • 2021-01-21 05:11

    In Windows there is a very useful function kbhit() but that is not there in linux unfortunately. There can be multiple methods for this. we'll make our own kbhit() method for linux. kbhit() will return non zero value when something is detected in the input buffer otherwise it will return 0 and pass on. In simple words it is non-blocking. Whenever the result is true then call getch() method to fetch that pressed key.

    #include <stdio.h>
    #include <termios.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/time.h>
    
    void changemode(int);
    int  kbhit(void);
    int main(void)
    {
      int ch;
      changemode(1);
      while ( !kbhit() );      // Waiting for some keyboard input.
    
      // something has been detected. now get that.
      ch = getchar();
    
      printf("\nGot %c\n", ch);
    
      changemode(0);
      return 0;
    }
    
    void changemode(int dir)
    {
      static struct termios oldt, newt;
    
      if ( dir == 1 )
      {
        tcgetattr( STDIN_FILENO, &oldt);
        newt = oldt;
        newt.c_lflag &= ~( ICANON | ECHO );
        tcsetattr( STDIN_FILENO, TCSANOW, &newt);
      }
      else
        tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
    }
    
    int kbhit (void) 
    {
      struct timeval tv;
      fd_set rdfs;
    
      tv.tv_sec = 0;
      tv.tv_usec = 0;
    
      FD_ZERO(&rdfs);
      FD_SET (STDIN_FILENO, &rdfs);
    
      select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
      return FD_ISSET(STDIN_FILENO, &rdfs);
    
    }
    
    0 讨论(0)
提交回复
热议问题