I'm reading a book and solving some problems. The question is
For each of the following pairs of
scanf
format strings, indicate whether or not the two strings are equivalent. If they're not, show how they can be distinguished.(a)
"%d"
veruss" %d"
(b)
"%d-%d-%d"
versus"%d -%d -%d"
(c)
"%f"
versus"%f "
(d)
"%f,%f"
versus"%f, %f"
My solution is (a) they are equivalent since scanf
discards the white space. For (b) they are not equivalent since scanf
matches -
with white space . For (c), they are not equivalent since
scanf
will put back the white space in the buffer. For (d), they are equivalent since scanf
discards white space. According to the Chegg solutions, all preceding questions are not equivalent. Am I wrong? In this post, I would like to make sure that my answers are correct in comparison with Chegg solutions. I've already read the book and I have decent knowledge about scanf
.
"%d"
and " %d"
are the same per OP's reasoning.
They are certainly the same with expected numeric input like "123"
and " 456"
. A remaining consideration would be where is the FILE
pointer on failure as with "abc"
versus " xyz"
? "%d"
by itself, first consumes leading white-space. So no difference.
... A conversion specification is executed in the following steps: C11dr §7.21.6.2 7
Input white-space characters ... are skipped, unless the specification includes a
[
,c
, orn
specifier. §7.21.6.2 8
then the conversion of text to numeric input (for "%d"
) happens.
Below code demonstrates equivalence.
void next_testi(const char *s, const char *fmt, const char *pad) {
rewind(stdin);
int i = 0;
int count = scanf(fmt, &i);
int next = fgetc(stdin);
printf("format:\"%s\",%s count:%2d, i:%2d, next:%2d, text:\"%s\"\n", //
fmt, pad, count, i, next, s);
}
void next_test(const char *s) {
FILE *fout = fopen("test.txt", "w");
fputs(s, fout);
fclose(fout);
freopen("test.txt", "r", stdin);
next_testi(s, "%d", " ");
next_testi(s, " %d", "");
puts("");
}
int main() {
next_test("3");
next_test(" 4");
next_test("");
next_test(" ");
next_test("+");
next_test(" -");
next_test("X");
next_test(" Y");
}
Output
format:"%d", count: 1, i: 3, next:-1, text:"3" // scanf() return value 1:success
format:" %d", count: 1, i: 3, next:-1, text:"3"
format:"%d", count: 1, i: 4, next:-1, text:" 4"
format:" %d", count: 1, i: 4, next:-1, text:" 4"
format:"%d", count:-1, i: 0, next:-1, text:"" // scanf() return value EOF, next is EOF
format:" %d", count:-1, i: 0, next:-1, text:""
format:"%d", count:-1, i: 0, next:-1, text:" "
format:" %d", count:-1, i: 0, next:-1, text:" "
format:"%d", count: 0, i: 0, next:43, text:"+" // scanf() return value 0
format:" %d", count: 0, i: 0, next:43, text:"+"
format:"%d", count: 0, i: 0, next:45, text:" -"
format:" %d", count: 0, i: 0, next:45, text:" -"
format:"%d", count: 0, i: 0, next:88, text:"X"
format:" %d", count: 0, i: 0, next:88, text:"X"
format:"%d", count: 0, i: 0, next:89, text:" Y"
format:" %d", count: 0, i: 0, next:89, text:" Y"
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