When you enter something that isn’t a number, scanf
will fail and will leave those characters on the input. So if you enter hello
, scanf will see the h
, reject it as not valid for a decimal number, and leave it on the input. The next time through the loop, scanf
will see the h
again, so it just keeps looping forever.
One solution to this problem is to read an entire line of input with fgets
and then parse the line with sscanf
. That way, if the sscanf
fails, nothing is left on the input. The user will have to enter a new line for fgets
to read.
Something along these lines:
char buffer[STRING_SIZE];
...
while(...) {
...
fgets(buffer, STRING_SIZE, stdin);
if ( sscanf(buffer, "%d", &price) == 1 )
break; // sscanf succeeded, end the loop
...
}
If you just do a getchar
as suggested in another answer, then you might miss the \n
character in case the user types something after the number (e.g. a whitespace, possibly followed by other characters).
You should always test the return value of sscanf
. It returns the number of conversions assigned, so if the return value isn’t the same as the number of conversions requested, it means that the parsing has failed. In this example, there is 1 conversion requested, so sscanf
returns 1 when it’s successful.