Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C – Can't correctly clear stdin before fgets

I’m having troubles cleaning the stdin. It’s a complex topic for which i searched all over the internet. I found many answers, but none helped me.

I will provide a little example program of what happens, and what behaviour i would want.

This is a program that waits for 3 seconds, then starts printing whatever i write.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

int main(int argc, char *argv[]){

char message[100] = {};
printf("Wait 3 seconds before you can write!\n");

sleep(3);

printf("Start writing!\n");
while (1) {
    while (fgets(message, 100, stdin) != NULL) {
      printf("You wrote: %s\n", message);
    }
}

}

My problem is: if i write things on the terminal while my program is sleeping, then the fgets() will print those things i wrote. It’s not what i would like. The correct behaviour should be that everything you wrote while sleeping should be discarded. Of course, the problem is that the things i previously wrote are still in the buffer.

This is an output example:

Wait 3 seconds befoure you can write!
hi
i don't want to wait

Start writing!
You wrote: hi
You wrote: i don't want to wait

To clear the stdin buffer, many mentioned using fflush(stdin) (while many others told this is an incorrect use of fflush, since it is used for stdout). Many others mentioned using this kind of function:

void clear_stdin() {
  int c;
  do {
    c = getchar();
  }   while (c != EOF && c != '\n');
}

But this doesn’t help me like it should. It only clear the first string i wrote on the terminal. I don’t know how the stdin’s buffer is implemented, but given its behaviour with this code, i think every time i write and press enter, it appends ‘\n’, but also a EOF. In my mind, EOF should be AT THE END of all the buffer. So, probably i have to change some conditions in my while, but i don’t know what.

Using this function in my code:

int main(int argc, char *argv[]){

char message[100] = {};
printf("Wait 3 seconds before you can write!\n");

sleep(3);

clear_stdin();

printf("Start writing!\n");

while (1) {
    while (fgets(message, 100, stdin) != NULL) {
      printf("You wrote: %s\n", message);
    }
}

}

And this is its output:

Wait 3 seconds befoure you can write!
hi
i don't want to wait

Start writing!
You wrote: i don't want to wait

Sorry for the wall of text. I tried giving you every bit of information possible. How can i totally clear the buffer?

>Solution :

For Windows and Linux

#ifdef _WIN32

  #include <windows.h>

  void clear_stdin()
  {
    FlushConsoleInputBuffer( GetStdHandle( STD_INPUT_HANDLE ) );
  }

  void sleep( unsigned timeout_ms )
  {
    Sleep( timeout_ms );
  }

#else

  #include <termios.h>
  #include <unistd.h>

  void clear_stdin()
  {
    tcflush( 0, TCIFLUSH );
  }

  void sleep( unsigned timeout_ms )
  {
    usleep( timeout_ms * 1000 );
  }

#endif

That should do it.

[edit] Added a sleep function for both systems for you too

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading