I was finishing up K&R exercises 7.4 and 7.5 and came across an annoying "feature" that I don't believe the standard states.
According to the K&R, the mode of action for the conversion specification "%c"
"The next input characters (default 1) are placed at the indicated spot. The normal skip over white space is suppressed; to read the next non-white space character, use %1s"
My question is, is that statement supposed to be read like:
"The next input characters (default 1) are placed at the indicated spot. THEN, in successive calls to scanf in which %c is used again, the normal skip over white space is suppressed; to read the next non-white space character, use %1s"
...because this code:
void test1()
{
char t1, t2;
scanf("%c %c", &t1, &t2);
printf("%d\n", t1);
printf("%d\n", t2);
//INPUT is: "b d" (without quotes)
}
results in t1 = 98 (b) and t2 = 100 (d). (Whitespace skipped)
However, this code:
void test2()
{
char t1, t2;
scanf("%c", &t1);
scanf("%c", &t2);
printf("%d\n", t1);
printf("%d\n", t2);
//INPUT is: "b d" (without quotes)
}
results in t1 = 98 (b) and t2 = 32 (' '). (Whitespace NOT skipped)
Reading the original quote, I think any reasonable person would take it to mean that during that same call to scanf(%c), the whitespace skip is suppressed. However, that doesn't seem to be the case.
It seems that in order to gain back the original functionality, one would have to completely empty stdin.
Is this supposed to work this way? Has it been documented? Because i've looked around and haven't seen much information on this.
For reference, I'm programming in C99.
This is because a space in the string passed to scanf means whitespace skip.
If you removed the space and used "%c%c" instead of "%c %c", the first program would behave exactly as the second.
So the answer to your question is: the normal skip is always suppressed, it's just the space that does the magic.
The man page for scanf on Linux states:
c Matches a sequence of characters whose length is specified by the maximum field width (default 1); the next pointer must be a pointer to char, and there must be enough room for all the characters (no terminating null byte is added). The usual skip of leading white space is suppressed. To skip white space first, use an explicit space in the format.
I believe that removes the ambiguity: c by itself does not skip whitespace; you must have an explicit space character in the format string. Therefore if you change your second example to:
scanf("%c", &t1);
scanf(" %c", &t1);
The second call to scanf will skip whitespace, because of the explicit whitespace character.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With