In line 5 I read an integer and isint
is getting 1 if it reads an integer or 0 if it's not an integer. If isint
is 0 I have a loop asking user to give an integer and I read until the user gives an integer. I try this code giving a character instead of an integer but I have an infinite loop. The program just doesn't wait to give a new input. What's wrong with my code?
#include <stdio.h>
int main(void) {
int arg1;
//int arg2;
int attacknum = 1;
int isint = 1;
//printf("Insert argument attacks and press 0 when you have done this.\n");
printf("Attack %d\n", attacknum);
attacknum++;
printf("Give attacking argument:");
isint = scanf("%d", &arg1); //line 5
while(isint == 0){
printf("You did not enter a number. Please enter an argument's number\n");
isint = scanf("%d", &arg1);
printf("is int is %d\n", isint);
}
return 0;
}
When
scanf
is confronted with a non-digit it will not consume any input and return that zero integers were read. The non-digit will stay in the input for the next call toscanf
that will behave the same as the first call, etc.In answer to your question below. You could use
fgetc
to parse at least one character, but this will give the error messages for every character already typed. Typically I think you want to skip until a newline. To this end you could usefgets
as suggested by poolie. Or you could add the following afterscanf
.P.S: In your case it is probably better to put it just before the first
printf
in the loop.As others have mentioned, if
scanf
can't parse the input, it leaves it unscanned.Generally
scanf
is a poor choice for interactive input because of this kind of behavior, and because it doesn't match the line-at-a-time interface experienced by the user.You are better off reading one line into a buffer using
fgets
. Then parse that line usingsscanf
. If you don't like the input, throw the whole line away and read another one.Something like this:
(For production code you'll want to handle long lines, check return codes, also check for trailing garbage after the number, etc.)
Actually, an even better approach would be to not use
scanf
if you just want to read an integer, and instead usestrtol
. That gives you a handy pointer to the character just after the number, and you can check that it's whitespace or nul.