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

为什么d";不等于%d";作为scanf中的格式字符串,c,scanf,C,Scanf,我在看书,解决一些问题。问题是 对于以下每对scanf格式字符串,指示 这两个字符串是否相等。如果他们不是,那就表演 如何区分它们 (a) “%d”veruss“%d” (b) %d-%d”与%d-%d” (c) “%f”与“%f” (d) %f,%f”与%f,%f” 我的解决方案是(a)它们是等价的,因为scanf丢弃了空白。对于(b),它们不相等,因为scanf将-与空格匹配。对于(c),它们是不等价的,因为scanf会将空白放回缓冲区。对于(d),它们是等效的,因为scanf丢弃空白。根据

我在看书,解决一些问题。问题是

对于以下每对
scanf
格式字符串,指示 这两个字符串是否相等。如果他们不是,那就表演 如何区分它们

(a)
“%d”
veruss
“%d”

(b)
%d-%d”
%d-%d”

(c)
“%f”
“%f”

(d)
%f,%f”
%f,%f”


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

你是对的,对选项(c)的推理稍加修改

“scanf将把空白放回缓冲区。”

我不太了解您的版本,但实际上,
scanf()
会将输入与提供的格式字符串进行逐字匹配,并且除了
%f
转换说明符之外,还需要将单个非前导空格与任意数量的空格进行匹配,直到读取到非空格为止

引用章节§7.21.6.2中的
C11

由空白字符组成的指令通过读取输入到 第一个非空白字符(保持未读状态),或直到无法读取更多字符 被阅读。该指令从未失败过

“%d”
“%d”
根据OP的推理是相同的

它们当然与预期的数字输入相同,如
“123”
“456”
。剩下的一个考虑因素是故障时的
文件
指针在哪里,就像
“abc”
“xyz”
一样<代码>%d“本身首先消耗前导空格。所以没有区别

。。。转换规范按以下步骤执行:C11dr§7.21.6.2 7

输入空白字符。。。跳过,除非规范包括
[
c
n
说明符。§7.21.6.2 8

然后将文本转换为数字输入(对于
“%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"

可能与@rsp重复,不完全相同。我已经提供了答案。此外,我正在将我的解决方案与Chegg解决方案进行比较。此外,这不是家庭作业问题。@CroCo有没有理由将列表格式还原为一段难以阅读的文本?@CroCo“根据Chegg解决方案”根据Cheng的书,与
%d
相比
%d
有什么区别?在(c)中,
scanf
将等待用户输入一个非空白字符,正如我从书中所理解的,因此我对选项不等价的说法是正确的。
%d-%d
%d-%d”
不一样。输入字符串
“1-2-3”
将不由前者解析,而是由latter@nos啊,我好像错过了,应该是对的。