Basically, I need to ensure that input is an integer, like so:
do {
printf("Enter > ");
scanf("%d", &integer);
} while (/* user entered a char instead of an int */);
I have tried various methods, but it always end up with run-time error or infinite loop when I tried to enter a char
. I have knew that fflush(stdin)
is an undefined behavior, which is better not to involve it in my code in order to prevent any error plus it no longer works in VS2015 due to some reasons.
The codes below are the method that I have tried:
typedef enum {false, true} bool;
int ipt;
char c;
bool wrong_ipt;
do {
c = '\0';
printf("Enter > ");
scanf("%d%c", &ipt, &c); //infinite loop occurs while a char has been entered
} while (c != '\n');
do {
c = '\0';
printf("Enter > ");
} while (scanf("%d", &ipt) != EOF);
do {
wrong_ipt = false;
do {
ipt = NULL;
printf("Enter > ");
scanf("%d", &ipt);
if (ipt == NULL) {
wrong_ipt = true;
break;
}
} while (ipt == NULL);
} while (wrong_ipt);
Is there anyway other than fflush(stdin)
which can be used to prevent the infinite loop when user entered a char
in C?
Thank you
The problem is that "scanf()" can leave unread data in your input buffer. Hence the "infinite loop".
Another issue is that you should validate the return value from scanf()
. If you expect one integer value ... and scanf returns "0" items read ... then you know something went wrong.
Here is an example:
#include <stdio.h>
void discard_junk ()
{
int c;
while((c = getchar()) != '\n' && c != EOF)
;
}
int main (int argc, char *argv[])
{
int integer, i;
do {
printf("Enter > ");
i = scanf("%d", &integer);
if (i == 1) {
printf ("Good value: %d\n", integer);
}
else {
printf ("BAD VALUE, i=%i!\n", i);
discard_junk ();
}
} while (i != 1);
return 0;
}
Sample output:
Enter > A
BAD VALUE, i=0!
Enter > B
BAD VALUE, i=0!
Enter > 1
Good value: 1