为什么"%d"不等于" %d"作为scanf中的格式字符串

时间:2017-04-07 11:14:01

标签: c scanf

我正在读书并解决一些问题。问题是

  

对于以下每对scanf格式字符串,请指明   这两个字符串是否相同。如果他们不是,请显示   如何区分它们。

     

(a)"%d" veruss " %d"

     

(b)"%d-%d-%d""%d -%d -%d"

     

(c)"%f""%f "

     

(d)"%f,%f""%f, %f"

我的解决方案是(a)它们是等效的,因为scanf丢弃了空格。对于(b),由于scanf-匹配空格,因此它们不相等。对于(c),它们不是等价的,因为scanf会将空白区域放回缓冲区。对于(d),它们是等价的,因为scanf丢弃了空格。根据Chegg解决方案,所有前面的问题都不相同。我错了吗?在这篇文章中,我想确保我的答案与Chegg解决方案相比是正确的。我已经读过这本书,而且我对scanf有很好的了解。

2 个答案:

答案 0 :(得分:1)

根据OP的推理,

"%d"" %d"是相同的。

它们与预期的数字输入肯定相同,例如"123"" 456"。剩下的考虑因素是FILE失败的指针与"abc"" xyz"的关系在哪里? "%d"本身,第一个消耗领先的空白区域。所以没有区别。

  

...转换规范按以下步骤执行:C11dr§7.21.6.27

     除非规范包含[cn说明符,否则将跳过

输入空白字符... §7.21.6.28

然后将文本转换为数字输入("%d")。

下面的代码演示了等效性。

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");
}

输出

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"

答案 1 :(得分:0)

你是正确的,对选项(c)推理稍作修改。

  

“scanf会将缓冲区中的空白区域放回来。”

我真的不了解你的版本,但实际上,scanf()字面上将输入与提供的格式字符串匹配,并且与%f转换说明符一起,单个非前导空格需要< em>匹配与任意数量的空格,直到读取非空格。

引用C11,章节§7.21.6.2

  

由白色空格字符组成的指令通过读取输入来执行   第一个非空格字符(仍未读取),或直到不再有字符   被阅读。该指令永远不会失败。