How to avoid pressing Enter with getchar() for reading a single character only?

后端 未结 12 1686
长发绾君心
长发绾君心 2020-11-22 00:33

In the next code:

#include 

int main(void) {   
  int c;   
  while ((c=getchar())!= EOF)      
    putchar(c); 
  return 0;
}
12条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-11-22 00:59

    "How to avoid pressing Enter with getchar()?"

    First of all, terminal input is commonly either line or fully buffered. This means that the operation system stores the actual input from the terminal into a buffer. Usually, this buffer is flushed to the program when f.e. \n was signalized/provided in stdin. This is f.e. made by a press to Enter.

    getchar() is just at the end of the chain. It has no ability to actually influence the buffering process.


    "How can I do this?"

    Ditch getchar() in the first place, if you don´t want to use specific system calls to change the behavior of the terminal explicitly like well explained in the other answers.

    There is unfortunately no standard library function and with that no portable way to flush the buffer at single character input. However, there are implementation-based and non-portable solutions.


    In Windows/MS-DOS, there are the getch() and getche() functions in the conio.h header file, which do exactly the thing you want - read a single character without the need to wait for the newline to flush the buffer.

    The main difference between getch() and getche() is that getch() does not immediately output the actual input character in the console, while getche() does. The additional "e" stands for echo.

    Example:

    #include 
    #include    
    
    int main (void) 
    {
        int c;
    
        while ((c = getche()) != EOF)
        {
            if (c == '\n')
            {
                break;
            }
    
            printf("\n");
        }
    
        return 0;
    }
    

    In Linux, a way to obtain direct character processing and output is to use the cbreak() and echo() options and the getch() and refresh() routines in the ncurses-library.

    Note, that you need to initialize the so called standard screen with the initscr() and close the same with the endwin() routines.

    Example:

    #include 
    #include    
    
    int main (void) 
    {
        int c;
    
        cbreak(); 
        echo();
    
        initscr();
    
        while ((c = getch()) != ERR)
        {
            if (c == '\n')
            {
                break;
            }
    
            printf("\n");
            refresh();
        }
    
        endwin();
    
        return 0;
    }
    

    Note: You need to invoke the compiler with the -lncurses option, so that the linker can search and find the ncurses-library.

提交回复
热议问题