Why doesn't scanf put characters back on failing?

Viewed 272

I know that scanf (and family) returns the number of arguments it successfully read. I also know that if it fails, the input remains untouched, so you can do stuff like this:

printf("%s", "Plese input a string or a float.\n");
float f;
char s[128];
if(scanf("%f", &f) == 1) {
    //do something to respond to user answering with a float. (1)
} else if(scanf("%127s", s)) {
    //do something to process the string. (2)
}

It turns out that scanf does mess with the input. I expect the scanf to try to read anything that matches <float here> and not do anything in case of a failure, but what happens instead, is scanf eating the input until whatever point it thinks is a good point to stop.

For example: If I input 1.2, I end up in branch (1) and f = 1.2 as expected.

If I input text the result is as expected, I end up in (2) and s = "text".

However, if the input is normal the result is that I end up in (2) without any extra user input and the value of s = "rmal". Why is no consumed is beyond me.

I am going to preemptively point out that, yes, I am using fgets instead of scanf, wherever possible, thank you for your suggestion.

The question remains the same: " Why does scanf consume input even on failure? "

3 Answers
Related