I have the following program:
int main(int argc, char *argv[])
{
int a, b;
char c1, c2;
printf("Enter something: ");
scanf("%d",&a); // line 1
printf("Enter other something: ");
scanf("%d", &b); // line 2
printf("Enter a char: ");
scanf("%c",&c1); // line 3
printf("Enter another char: ");
scanf("%c", &c2); // line 4
printf("Done"); // line 5
system("PAUSE");
return 0;
}
As I read in the C book, the author says that scanf()
left a new line character in the buffer, therefore, the program does not stop at line 4 for user to enter the data, rather it stores the new line character in c2 and moves to line 5.
Is that right?
However, does this only happen with char
data types? Because I did not see this problem with int
data types as in line 1, 2, 3. Is it right?
The scanf()
function removes whitespace automatically before trying to parse conversions other than characters. The character formats (primarily %c
; also scan sets %[…]
— and %n
) are the exception; they don't remove whitespace.
Use " %c"
with a leading blank to skip optional white space. Do not use a trailing blank in a scanf()
format string.
Note that this still doesn't consume any trailing whitespace left in the input stream, not even to the end of a line, so beware of that if also using getchar()
or fgets()
on the same input stream. We're just getting scanf to skip over whitespace before conversions, like it does for %d
and other non-character conversions.
Note that non-whitespace "directives" (to use POSIX scanf terminology) other than conversions, like the literal text in scanf("order = %d", &order);
doesn't skip whitespace either. The literal order
has to match the next character to be read.
So you probably want " order = %d"
there if you want to skip a newline from the previous line but still require a literal match on a fixed string, like this question.
Use scanf(" %c", &c2);
. This will solve your problem.
Another option (that I got from here) is to read and discard the newline by using the assignment-supression option. To do that, we just put a format to read a character with an asterisk between %
and c
:
scanf("%d%*c",&a); // line 1
scanf("%c%*c",&c1); // line 3
scanf
will then read the next char (that is, the newline) but not assign it to any pointer.
In the end, however, I would second the FAQ's last option:
Or, depending on your requirements, you could also forget about scanf()/getchar(), use fgets() to get a line of text from the user and parse it yourself.
Use getchar()
before calling second scanf()
.
scanf("%c", &c1);
getchar(); // <== remove newline
scanf("%c", &c2);