Please see the following code:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int n;
int i = scanf("%d", &n);
printf("%d\n", i);
int j = scanf("%d", &n);
printf("%d\n", j);
return 0;
}
Suppose I input a string for n
at the first time, scanf
will return 0
; however, why it won't allow me to input a value for n
the second time and j
is automatic 0
? What should I do to make it allow me to input a value for n
again even if I typed a wrong value at the first time?
You're almost certainly entering a non-numeric value, which will cause the first scanf
to fail, returning zero and (this is the important bit) leaving the stream pointer exactly where it was before the scanf
call.
That means the next time you call it, it will simply try to read the same data.
The return value of zero is a dead giveaway - scanf
returns the number of items successfully scanned, so zero means you didn't give it a number.
If you enter numbers, it works fine, as per the following code:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int n;
int i = scanf("%d", &n);
printf(">> %d %d\n", i, n);
int j = scanf("%d", &n);
printf(">> %d %d\n", j, n);
return 0;
}
When you run that and enter 41
and 32
, you see:
41
>> 1 41
32
>> 1 32
Every C programmer at some point in their career comes up against the inadequacies of user input in that language. Your best bet for line based input is to simply find a function that does it well, then use sscanf
on the resultant string.
One that ensures lines are the basic unit, and can handle buffer overflows and making sure excess data doesn't "corrupt" future input.
Here's one I prepared earlier.
The non-numeric string you entered isn't consumed by scanf
.
Instead, you can use fgets
and sscanf
like this:
#include <stdio.h>
int main(void)
{
int n;
char str[100];
fgets(str, sizeof(str), stdin);
int i = sscanf(str, "%d", &n);
printf("%d\n", i);
fgets(str, sizeof(str), stdin);
int j = sscanf(str, "%d", &n);
printf("%d\n", j);
return 0;
}
You can ignore the rest of the line before entering input afresh and reading them. You can ignore the rest of the line using:
scanf("%[^\n]*\n");
If you enter numbers your code will work fine. However, when you are entering a string, then you must remove the string from input stream before using it again.
For example:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int n;
char c;
int i = scanf("%d", &n);
printf("%d\n", i);
//Remove the previous string from the input stream
while ( (c = getchar()) != '\n' && c != EOF );
int j = scanf("%d", &n);
printf("%d\n", j);
return 0;
}
Output when input is integer
100
1
200
1
Output when input is strings
abcd
0
efghi
0
For further reference: Why does everyone say not to use scanf? What should I use instead?