This question already has an answer here:
-
Scanf is not scanning %c character but skips the statement, why is that?
4 answers
I was recently running a c program in my PC. It have a for loop in which some char d is scanned. The for loop runs for 3 times. During each running it prints the the count of running and then scans the value of char d. The program is as follows
#include<stdio.h>
int main(){
int f;
char d;
for(f=0;f<3;f++){
printf("Choice %d\n", f);
scanf("%c", &d);
}
return 0;
}
Now the trouble is that when I run the program, the for skips the scanf part when f is 1.
Now if i changed the code as follows
#include<stdio.h>
int main(){
int f;
int d;
for(f=0;f<3;f++){
printf("Choice %d\n", f);
scanf("%d", &d);
}
return 0;
}
Now the program works fine. and scanf is executed for every iteration of for loop.
What does seem to be the problem here? I mean when d is of type int it works fine, but when d is of type char it does not work correctly.
You have to change
scanf("%c", &d);
to
scanf(" %c", &d);
^
|
Otherwise, scanf()
will consider the previously entered ENTER
key press.
Note:
ENTER key press generates a \n
, which is a vaild input for %c
format specifier. Adding a space before %c
tells scanf()
to ignore all leading whitespace-like inputs (including that previously stored \n
) and read the first non-whitespace character from stdin
.
As for the case with %d
format specifier, it consumes (and ignores) any leading whitespace-like inputs before scanning for numeric inputs, so the second case does not suffer any issues.
The problem is that when you enter a character for scanf("%c", &d);
, you press the enter key. The character is consumed by the scanf
and the newline character stays in the standard input stream(stdin
). When scanf
(with %c
) is called the next time, it sees the \n
character in the stdin
and consumes it, and thus does not wait for further input.
To fix it, change
scanf("%c", &d);
to
scanf(" %c", &d);
// ^Note the space before %c
The space before the %c
instructs scanf
to scan any number of whitespace characters including none and stops scanning when it encounters a non-whitespace character. Quoting the standard:
7.21.6.2 The fscanf function
[...]
- A directive composed of white-space character(s) is executed by reading input up to the
first non-white-space character (which remains unread), or until no more characters can
be read. The directive never fails.
The reason that using %d
worked is that the %d
format specifier automatically skips whitespace characters and since \n
is a whitespace character, %d
does not scan it. Quoting the standard again:
7.21.6.2 The fscanf function
[...]
- Input white-space characters (as specified by the
isspace
function) are skipped, unless
the specification includes a [
, c
, or n
specifier. 284