scanf
is a strange function, and there's a classic line from the movie WarGames that's relevant: "The only winning move is not to play".
If you find yourself needing to "flush input", you have already lost. The winning move is not to search desperately for some magic way to flush the nettlesome input: instead, what you need to do is to do input in some different (better) way, that doesn't involve leaving unread input on the input stream, and having it sit there and cause problems, such that you have to try to flush it instead.
There are basically three cases:
You are reading input using scanf
, and it is leaving the user's newline on the input stream, and that stray newline is wrongly getting read by a later call to getchar
or fgets
. (This is the case you were initially asking about.)
You are reading input using scanf
, and it is leaving the user's newline on the input stream, and that stray newline is wrongly getting read by a later call to scanf("%c")
.
You are reading numeric input using scanf
, and the user is typing non-numeric text, and the non-numeric text is getting left on the input stream, meaning that the next call to scanf
fails on it also.
In all three cases, it may seem like the right thing to do is to "flush" the offending input. And you can try, but it's cumbersome at best and impossible at worst. In the end I believe that trying to flush input is the wrong approach, and that there are better ways, depending on which case you were worried about:
In case 1, the better solution is, do not mix calls to scanf
with other input functions. Either do all your input with scanf
, or do all your input with getchar
and/or fgets
. To do all your input with scanf
, you can replace calls to getchar
with scanf("%c")
— but see point 2. Theoretically you can replace calls to fgets
with scanf("%[^\n]%*c")
, although this has all sorts of further problems and I do not recommend it. To do all your input with fgets
even though you wanted/needed some of scanf
's parsing, you can read lines using fgets
and then parse them after the fact using sscanf
.
In case 2, the better solution is, never use scanf("%c")
. Use scanf(" %c")
instead. The magic extra space makes all the difference. (There's a long explanation of what that extra space does and why it helps, but it's beyond the scope of this answer.)
And in case 3, I'm afraid that there simply is no good solution. scanf
has many problems, and one of its many problems is that its error handling is terrible. If you want to write a simple program that reads numeric input, and if you can assume that the user will always type proper numeric input when prompted to, then scanf("%d")
can be an adequate — barely adequate — input method. But perhaps your goal is to do better. Perhaps you'd like to prompt the user for some numeric input, and check that the user did in fact enter numeric input, and if not, print an error message and ask the user to try again. In that case, I believe that for all intents and purposes you cannot meet this goal based around scanf
. You can try, but it's like putting a onesie on a squirming baby: after getting both legs and one arm in, while you're trying to get the second arm in, one leg will have wriggled out. It is just far too much work to try to read and validate possibly-incorrect numeric input using scanf
. It is far, far easier to do it some other way.
You will notice a theme running through all three cases I listed: they all began with "You are reading input using scanf
...". There's a certain inescapable conclusion here. See this other question: What can I use for input conversion instead of scanf?
Now, I realize I still haven't answered the question you actually asked. When people ask, "How do I do X?", it can be really frustrating when all the answers are, "You shouldn't want to do X." If you really, really want to flush input, then besides the other answers people have given you here, two other good questions full of relevant answers are:
\r
). When you press Enter, depending on your system, it may emit a\r
(old Macs),\r\n
(Windows) or a\n
(virtually every other OS, including OSX/macOS). The answers already cover how the C runtime collapses the Windows\r\n
to just\n
on text mode streams for you. – Hexone