Reputation: 53
im a beginner to C,, and i was writing a code to print a square of a user entered character.
usually when we need to input two integers (say x and y) using scanf()
we write this scanf("%d%d", &x, &y)
but according to the needs of my code i am supposed to input one integer (say m) and a character (say ch).
I wrote it as scanf("%d%c", &x, &ch)
but it has an error, when i execute the program it only asks the integral value to be entered and then it just stop executing.
I searched for this and i found that i need to put space between %d
and %c
as scanf("%d %c", &x, &ch);
Can anyone explain this why we need to put space between this?
Upvotes: 5
Views: 2826
Reputation: 206717
Meaning of whitespace characters in the format string (from http://www.cplusplus.com/reference/cstdio/scanf/?kw=scanf):
Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters -- see isspace). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).
When your code is:
scanf("%d%c", &x, &ch)
and you enter
10
in your console:
10
is read and stored in x
.ch
.If you use
scanf("%d %c", &x, &ch)
and you enter
10
10
is read and stored in x
.ch
. This is because stdin
is typically line buffered.Upvotes: 12
Reputation: 320739
Almost all format specifiers in scanf
automatically skip all whitespace before trying to read anything. That's, for example, how %d
works (as well as %s
, %f
and most other specifiers). However, %c
is an exception from this behavior. %c
does not skip whitespace. If your input data contains a whitespace character, %c
will happily read that character into your ch
variable.
This is most likely what happens in your case. If you enter
5 #
to create a 5x5 square of #
s, the %d
specifier will read 5
into x
and stop reading at the space character. Then %c
will read that space character into ch
. And then your program will just proceed, leaving the #
unread. It is quite possible that the rest of your program actually works as intended. It's just that since ch
is a space character, it displays a 5x5 square of space characters, which are invisible :) To make your scanf
in its original form work as intended you have to input your data as
5#
But a much better way to make sure that your scanf
actually reads the #
character into ch
is to explicitly ask scanf
to skip all whitespace before reading ch
. In scanf
this is done by inserting any whitespace character (space, newline, tab etc.) into the format string. This
scanf("%d %c", &x, &ch);
will force scanf
to skip that space after 5
and read the #
into ch
. This will also work for inputs like this
5 #
and even like this
5
#
because scanf
will automatically skip all whitespace until it hits the #
. Note also that even with the updated format sting whitespace in the input is not required, meaning that this input
5#
will still work with the updated scanf
.
You can also use these variants
scanf("%d\t%c", &x, &ch);
scanf("%d\n%c", &x, &ch);
scanf("%d %c", &x, &ch);
scanf("%d \n \t %c", &x, &ch);
to achieve the same thing. They are all equivalent. The first variant (with a space) just looks better.
Upvotes: 4