how to properly flush the input stream (stdin)

jephthah 0 Tallied Votes 6K Views Share

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
jephthah 1,888 Posting Maven

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

William Hemsworth 1,339 Posting Virtuoso

Rofl :]

Adak 419 Nearly a Posting Virtuoso

It's good. ;)

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

smoothment 0 Newbie Poster

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

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

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.

David_50 13 Junior Poster in Training

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.

David_50 13 Junior Poster in Training

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.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.