Thread: How to check if stdin is empty before clearing anything left in stdin

  1. #16
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Quote Originally Posted by rstanley View Post
    Once again, I don't recommend the use of conio.h or ANY MS extension to the C Programming Language!

    You are locking yourself into a Windows compiler environment. The code CANNOT be ported to Linux or any other non-windows compiler, without replacing the MS specific functions.

    Please stick to Standard C, and please advise others to do so as well!!!
    There is nothing wrong with using conio.h if you are aware that it won't work outside of windows and you don't intend it to. When it comes to writing code for command prompt on Windows, it's actually quite a powerful library.

    No one bats an eyelid when people suggest Linux specific code...

  2. #17
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,110
    Quote Originally Posted by Click_here View Post
    There is nothing wrong with using conio.h if you are aware that it won't work outside of windows and you don't intend it to. When it comes to writing code for command prompt on Windows, it's actually quite a powerful library.
    I, and many others would strongly disagree.

    Quote Originally Posted by Click_here View Post
    No one bats an eyelid when people suggest Linux specific code...
    Would you care to give some examples? Perhaps in a new thread.

    There are differences between different O/S's, such as having to deal with Binary mode, vs. Text mode in Windows when dealing with Windows/DOS text file termination, for example.

  3. #18
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    rstanley:

    Quote Originally Posted by flp1969 View Post
    I don't have the slightest idea on how to do this on Windows (and I don't care!). To check if the standard input has any data available, in Linux, is simple:
    Code:
    struct pollfd pfd = { .fd = fileno( stdin ), .events = POLLIN };
    if ( poll( &pfd, 1, 0 ) > 0 )
      if ( pfd.revents & POLLIN ) { ... there is data in stdin ... }
    On other Unix systems you can use select()...
    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  4. #19
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,110
    Quote Originally Posted by mweston379 View Post
    I have been using the code...
    while (getchar() != '\n');
    ...to clear everything in stdin in my programs. However, I am running into a slight issue on some occasions. There are times in my programs where when I call getchar(), there may or may not be anything in stdin. When it is the case that there is nothing in stdin, what ends up happening is getchar() is called and it is waiting for something in stdin. I then have to enter \n on my keyboard otherwise the program is just stuck on that one line. I am wondering if there is a simple way to first check if stdin is empty before doing while (getchar() != '\n'); in order to avoid this problem?

    Not sure if the compiler matters for the answer, but I am using Visual Studio 2017.
    I would really have to know more about what you are trying to do with the code, but please accept the following.

    The following should be true for all hosted O/S's using Standard C.

    Text input in C is normally line oriented. fgets() and getchar() (And related functions) will wait till a newline is input from the keyboard or if reading from a disk file, or if using redirection from a disk file. You will need to check the return value to also test for errors or EOF.

    When you start the program, you can be certain that the stdin buffer is empty.

    Normally you would use fgets() to input an entire input string and use sscanf() to process the string. If using fgets() and the newline has NOT been input, then the line being input is longer than the array passed to fgets() and you will need multiple calls to fgets() to input the entire line.

    EOF can be input from the keyboard using a [Ctrl]-[D], in Linux/UNIX, or [Ctrl]-[Z], in Windows.

    If a newline has been received, then the stdin buffer can be assumed to be empty. Otherwise, there may be more data in the stdin buffer.

    If EOF has been detected, from the keyboard, or from a disk file, don't attempt to input more data.

    If using getchar(), and the newline has not yet been received, AND you no longer want any other data from the stdin buffer including the newline, use the following code to clear the stdin buffer:


    Code:
    void flush_in(void)
    {
       int ch = 0;
    
       while ((ch = getchar()) != '\n' && ch != EOF);
    }
    Using all the above, you should normally not need to somehow look in the stdin buffer to see if any data is there. Bottom line, the newline is the key to know if any more data remains in the stdin buffer.

    If this does not answer your question, please provide code or further explanation .

  5. #20
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Code:
    #include <unistd.h>
    #include <stdio.h>
    
    #ifndef __linux__
    # error Compile only on linux!
    #endif
    
    #include <poll.h>
    
    int _getch( void )
    {
      // We need to use an unbuffered descriptor.
      // Streams (like stdin and stdout) are buffered and this will not work!
    
      struct pollfd pfd = { .fd = STDIN_FILENO, .events = POLLIN };
      char c;
    
      // Flush stdin if there are any chars pending...
      while ( poll( &pfd, 1, 0 ) > 0 )
        read( STDIN_FILENO, &c, sizeof c );
    
      if ( read( STDIN_FILENO, &c, sizeof c ) < 0 )
        return EOF;
    
      return c;
    }
    
    int main( void )
    {
      // Change _getch() calls to getchar() and you'll see the second one
      // won't wait for keyboard input.
      // PS: getch() isn't standard!
    
      fputs( "Fist char: ", stdout ); fflush( stdout );
      _getch();
      fputs( "Second char: ", stdout ); fflush( stdout );
      _getch();
      fputs( "Finish.\n", stdout );
    }
    PS: Use termios (tcgetattr/tcsetattr) to ignore CR, if you want...
    Last edited by flp1969; 07-07-2019 at 08:56 AM.

  6. #21
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    kbhit() and getch() for WINDOWS:
    Code:
    #include <windows.h>
      
    int _kbhit(void)
    {
      HANDLE hConsole;
      INPUT_RECORD ir;
      DWORD n;
     
      hConsole = GetStdHandle(STD_INPUT_HANDLE);
      while (PeekConsoleInput(hConsole, &ir, 1, &n))
        if (ir.EventType == KEY_EVENT)
          return 1;
      
      return 0;
    }
    
    // I don't remember if this function requires an <ENTER>
    // as in getchar()...
    int _getch(void)
    {
      HANDLE hConsole;
      DWORD cm, n;
      char buffer[4];   // Probably 2 bytes will be sufficient...
                       // Using 4 to be sure...
    
      hConsole = GetStdHandle(STD_INPUT_HANDLE);
      GetConsoleMode(hConsole, &cm);
      SetConsoleMode(hConsole, cm &
                 ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT));
      ReadConsole(hConsole, buffer, 1, &n, NULL);
      SetConsoleMode(hConsole, cm);
      
      // Just 1 char needed!
      return buffer[0];
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Clearing stdin
    By qwertyuiop23 in forum C Programming
    Replies: 6
    Last Post: 08-14-2011, 11:54 PM
  2. Blocking or clearing stdin
    By woopitt in forum C Programming
    Replies: 4
    Last Post: 05-23-2011, 05:05 PM
  3. How to check if stdin needs to be flushed?
    By DKarhi in forum C Programming
    Replies: 4
    Last Post: 09-20-2007, 04:51 PM
  4. Newbie Question - fflush(stdin) & fpurge(stdin) on Mac and PC
    By tvsinesperanto in forum C Programming
    Replies: 34
    Last Post: 03-11-2006, 12:13 PM
  5. ascii 10 in the stdin after fflush(stdin)??
    By Kev2 in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 06-03-2002, 03:53 PM

Tags for this Thread