5

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.

melpomene
  • 84,125
  • 8
  • 85
  • 148
CroCo
  • 5,531
  • 9
  • 56
  • 88
  • 1
    Possible duplicate of [Difference between different scanf formats](http://stackoverflow.com/questions/38126126/difference-between-different-scanf-formats) – msc Apr 07 '17 at 11:16
  • 1
    @rsp, not exactly. I've already provided answers. Also, I'm comparing my solutions to Chegg solutions. Moreover, it is not homework question. – CroCo Apr 07 '17 at 11:18
  • @CroCo any reason to revert the list formatting to a chunk of tough-to-read text? – Sourav Ghosh Apr 07 '17 at 11:28
  • @CroCo "According to the Chegg solutions" --> According to the book by Cheng, what is the difference between `"%d"` versus `" %d"`? – chux - Reinstate Monica Apr 07 '17 at 13:49

2 Answers2

2

"%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, or n 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"
Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

You are correct, with a little modification to option (c) reasoning.

"scanf will put back the white space in the buffer."

I don't really understand your version, but actually, scanf() literally matches the input with the supplied format string, and alongside %f conversion specifier, a single non-leading whitespace needs to be matched with any number of whitespaces, until a non-whitespace is read.

Quoting C11, chapter §7.21.6.2

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.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • In (c), `scanf` will wait until the user enters a non-white-space character, as I understood from the book, so my claim for the options being not equivalent is correct. – CroCo Apr 07 '17 at 11:47
  • `"%d-%d-%d"` and `"%d -%d -%d"` are not the same. An input string of `"1- 2 -3"` will not be parsed by the former, but will be parsed by the latter – nos Apr 07 '17 at 11:47
  • @nos Ahh, I seem to have miss that, should be right. – Sourav Ghosh Apr 07 '17 at 11:49