how to properly flush the input stream (stdin)

 
0
 

too many new and intermediate users of C attempt to use the command fflush(stdin) to "flush the input buffer". this is patently wrong.

the rule is (and click if you don't believe me) : NEVER USE "FFLUSH()" ON INPUT STREAMS SUCH AS "STDIN"

here is one method of properly flushing extra (and unwanted) characters from the stdin input stream. the code is written as a macro, and requires a character array to collect excess (junk) input. the macro will also ensure the newline character is stripped.

the intended use is in conjunction with fgets. for example:

char userInput[8]; // change array size to any arbitrary value

    printf("input a string and hit <enter>.  A maximum of %d characters will be recorded.\n",sizeof(userInput)-1);

    fgets(userInput,sizeof(userInput),stdin);
    FLUSH_STDIN(userInput);    // strip newline, flush extra chars

    printf("the first %d characters are \"%s\", any others have been discarded.\n",strlen(userInput),userInput);
#define FLUSH_STDIN(x) {if(x[strlen(x)-1]!='\n'){do fgets(Junk,16,stdin);while(Junk[strlen(Junk)-1]!='\n');}else x[strlen(x)-1]='\0';}

char Junk[16]; // buffer for discarding excessive user input, 
               // used by "FLUSH_STDIN" macro
 
0
 

wow, dude, this snippet rocks! A+++ would read again!

 
0
 

Rofl :]

 
0
 

It's good. ;)

The one I like moves the stream pointer for the keyboard - very elegant, but everybody asks WTF is THAT?

 
0
 

That is a fantastic solution, you are my hero :)))

 
0
 

That is a fantastic solution

Eh, I'm not a fan of it. It's tied heavily to fgets, requires a special buffer that can easily cause name conflicts, lacks flexibility in where it can be called, and ignores error handling. It's inefficient in general, and most importantly, neglects that the newline handling of fgets is there for a reason. Instead of calling characters beyond the length of your buffer "junk" and throwing them away, robust code will at best allow them somehow and at worst gracefully refrain from actively deleting data.

 
0
 

Now, if stdin is a pipe or such, a read() too big will stall, so many apps read() one byte at a time to get earlier access to input.

 
0
 

For C I/O in a line oriented text milieu, fgets() is fine: returns null on error or EOF, is supported by ferror(), perror(), feof() (not necessary, as if a null return is not an error, it is EOF). The only caveat is that you need a long line detection, which can simply be that if the last byte of your buffer is set to null and the prior byte is not a linefeed, your buffer was too short for the line, and you have just the first part of the line. How you handle that is policy: ignore, error out or realloc() a bigger buffer and fgets() on top of the trailing null byte for additional space plus 1.

Isn't it about time forums rewarded their contributors?

Earn rewards points for helping others. Gain kudos. Cash out. Get better answers yourself.

It's as simple as contributing editorial or replying to discussions labeled or OP Kudos

You
This is an OP Kudos discussion and contributors may be rewarded
Post:
Start New Discussion
View similar articles that have also been tagged: