scanf is supposed to consume and discard any character in the format string that is not part of a conversion specifier. But its behavior seems different when a non-whitespace, non-conversion character comes first in the format string. Why?
int main() {
int num, num2;
printf("> ");
while (scanf("> %d %d", &num, &num2)) {
printf("You entered the number %d %d.\n", num, num2);
printf("> ");
}
return EXIT_SUCCESS;
}
If you build and run this and enter
> 3 4
at the prompt, it prints the message and the repeated prompt and then quits immediately.
So that means that scanf returns 2 the first time and then returns 0 before the user can enter another set of tokens. If you remove the > from the format string, the loop will run until the user enters something not a numeral, which then causes scanf to return 0 - the behavior I would expect.
Also, if I put that same symbol after the first conversion specifier, the loop continues to run as expected. That is, if the format string has, say, "%d > %d", and the user enters
3 > 4
the loop will run again and accept another round of input.
I have not seen any documentation on this behavior.
scanf, why not walk through the string with a pointer and just figure this out yourself? Figuring out simple syntax like this is pretty close to trivial.'>'with the newline reamining in the input, so it failed." > %d %d"to avoid that issue. Your read-loop test must bewhile (scanf("> %d %d", &num, &num2) == 2)otherwise, it will fail (spectacularly) if a manual EOF is entered. (see @pmg comment below for proper solution) Read it all into a buffer and then callsscanf()on the buffer instead of reading withscanf()directly.scanf()for user input.scanf()was not designed for user input. Usefgets()instead."unrealated:"... Bottom line is the'\n'is generated by you pressing[Enter]following input.'>'is NOT a conversion specifier and has no ability to read/discard whitespace. Adding a space before allows zero-or-more whitespace to be discarded. Failing to check== 2invites undefined behavior. His point is usingfgets()and a sufficiently sized buffer avoids that pitfall inscanf()use completely.