问题
// program to detect whether only integer has been given or not
int main() {
int a, b, s;
printf("Enter two proper number\n");
BEGIN:
s = scanf("%d %d", &a, &b); //storing the scanf return value in s
if (s != 2) {
printf("enter proper value\n");
goto BEGIN;
}
printf("The values are %d and %d ", a, b);
}
This program to detect whether only integer has been given or not goes into infinite loop when invalid data is entered instead of asking for new values
why doesn't the goto
work here?
回答1:
Note that when scanf
gets bad input (for example you enter cat dog) that input remains in the input buffer until you take steps to clear it out. So the loop keeps repeating and rejecting the same input which is still there.
It is simpler to use fgets
and sscanf
and if the scan fails, you just forget the input string and get another.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a, b;
char str[42];
do {
printf("Enter 2 numeric values\n");
if(fgets(str, sizeof str, stdin) == NULL) {
exit(1);
}
} while(sscanf(str, "%d%d", &a, &b) != 2);
printf("Numbers are %d and %d\n", a, b);
}
Program session:
Enter 2 numeric values cat dog Enter 2 numeric values cat 43 Enter 2 numeric values 42 dog Enter 2 numeric values 42 43 Numbers are 42 and 43
Note that goto
is poor practice in C and should be used only where there is no other way of constructing the code — which there usually is.
回答2:
There are multiple reasons scanf()
can return a value different from 2
:
- there is pending input that cannot be converted according to the conversion specification. For example if there is an
A
pending in the input stream, the%d
conversion fails and theA
stays in the input stream. Your code just keeps trying this conversion and will never stop. You should read and discard the offending input before re-trying. - the input stream has had a read error or hit the end of file. If at least one conversion succeeded, the number of successful conversions is returned, otherwise
EOF
is returned. IfEOF
is returned, there is no point trying again since no more input will be available. - Note also that it is considered bad style to use
goto
for constructions that are better expressed with flow control statements such aswhile
andfor
.
Here is a corrected version:
#include <stdio.h>
// program to detect whether only integer has been given or not
int main() {
int a, b, s, c;
printf("Enter two proper numbers: ");
for (;;) {
s = scanf("%d%d", &a, &b); //storing the scanf return value in s
if (s == 2) // conversions successful
break;
if (s == EOF) {
printf("unexpected end of file\n");
return 1;
}
/* discard the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
printf("Invalid input. Try again: ");
}
printf("The values are %d and %d\n", a, b);
return 0;
}
回答3:
scanf returns the number of characters. As a result, s
will be equal to the number of characters you have written is 2, then your loop will stop. The reason this runs infinitely many times is that the number of characters you have entered differed from 2. Print s to see what value it holds and you will get more information.
来源:https://stackoverflow.com/questions/52795781/program-to-detect-whether-only-integer-has-been-given-or-not-goes-into-infinite