cioansi-cgcc-pedantic

Function to read a key without waiting for LF


I'm looking throughout the Internet in search of some function that will read a key from keyboard without waiting for LF (like getch() from conio.h). Unfortunately I have to compile it with gcc using switches -ansi and -pedantic, which makes getch() useless to me. Maybe you know some other function that'll match standards?


Solution

  • You can use the standard setvbuf function to disable buffering (see example below). Note that this will cause buffering to be disabled from the point of view of your program, but not disable buffering in the terminal (which might also be what you want). Example code:

    #include <stdio.h>
    
    int main()
    {
            char c;
            setvbuf(stdin, 0, _IONBF, 0);
            c = getc(stdin);
            printf("read %c\n", c);
    
            return 0;
    }
    

    Running it like this will still read input from the terminal line-wise but only consumes the first character entered:

    $ ./buf
    ab
    read a
    $ b
    

    Removing the setvbuf line will cause the whole line of input to be consumed by your program.

    There is no portable way to disable the line-buffering of the terminal if using the C standard library only, since it doesn't know about terminals.

    EDIT:

    One POSIX-portable way of doing what you want is to use the termios functions:

    #include <stdio.h>
    #include <unistd.h> /* for STDIN_FILENO */
    #include <termios.h>
    
    int main()
    {
            char c;
            struct termios old, t;
    
            tcgetattr(STDIN_FILENO, &old);
            t = old;
            cfmakeraw(&t);
            tcsetattr(STDIN_FILENO, TCSANOW, &t);
            c = getc(stdin);
            tcsetattr(STDIN_FILENO, TCSANOW, &old);
            printf("\rread %c\n", c);
    
            return 0;
    }