Start New Discussion within our Software Development Community

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);

    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

It's good. ;)

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

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.

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.

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.

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.