The simple answer is to loop until valid input has been read (assuming the input comes from an interactive agent such as a person sat at a terminal).
The following will not work:
switch(selectedOption){
case 'B':
while (1) {
printf("Please enter the first number\n");
if (scanf("%f", &firstNumber) == 1){
printf("Is a valid number\n");
break;
}
else{
printf("Is not a valid number\n");
}
}
/* ... */
break;
}
The problem is that scanf
will stop reading input when it sees a character that is not part of the number, and will push that character back onto the stream (c.f. ungetc
). For example, if the input is -foo
, scanf
will read the spaces, then the -
(which could be part of the number), then the f
which is not part of the number. The f
will be pushed back onto the stream and scanf
will return 0. On the next iteration of the while loop, scanf
will read the f
, push it back onto the stream and return 0. Loop ad infinitum, et ultra.
To break the infinite loop, the code needs to read something from the stream and discard it. One option is to read and discard the next word by calling scanf("%*s");
, or discard the next word and the following whitespace character by calling scanf("%*s%*c");
, or discard the remainder of the line and the newline by calling scanf("%*[^\n]%*c");
. E.g.:
switch(selectedOption){
case 'B':
while (1) {
printf("Please enter the first number\n");
if (scanf("%f", &firstNumber) == 1){
printf("Is a valid number\n");
break;
}
else{
printf("Is not a valid number\n");
scanf("%*s");
}
}
/* ... */
break;
}
Note that input such as 42foo
will be considered valid by the above code. scanf
will push the f
back onto the stream and return 1 because it has read a valid number 42
. You may want to read the next character and check that it makes sense. You can always push at least one character back onto the stream by calling ungetc(ch, stdin);
so that it can be re-read later.