【问题标题】:Is an fscanf/scanf/sscanf conversion specification with assignment suppressed not a conversion?分配被抑制的 fscanf/scanf/sscanf 转换规范不是转换吗?
【发布时间】:2021-08-04 18:47:11
【问题描述】:

sscanf("x", "%*c%c", &(char){0}) 应该返回什么?

Apple 和 Godbolt 使用的库返回 -1,即他们的 EOF。但是,C 2018 7.21.6.7 3 告诉我们sscanf 返回“EOF 如果在第一次转换(如果有)完成之前发生输入故障。” %*c 是一个禁止赋值的转换规范。它完成,然后在%c 完成之前发生输入失败(字符串结尾)。然后sscanf 应该返回“分配的输入项的数量”,即为零。

标准中是否有任何文字告诉我们%*c 不被视为转换?

【问题讨论】:

  • IMO 转换发生在扫描值分配给scanf 的参数时。否则只是格式字符串的一部分
  • 在规范中似乎是一个简单的错字:“第一次转换”应该是“第一次赋值”,因为返回值只与赋值数有关。

标签: c language-lawyer


【解决方案1】:

显然 C99 §7.19.6.2 第 15 点(和 C17 §7.21.6.2 第 15 点)告诉我们:

尾随空格(包括换行符)未被读取,除非匹配 指示。 文字匹配和抑制赋值的成功不是直接的 可以通过%n 指令以外的方式确定。

“抑制分配”定义为 %* 后跟说明符。

因此,您在示例中看到的内容似乎符合标准:您无法推断 %*c 是否匹配,除非您使用 n 说明符来计算扫描字符的数量。

此外,user3386109this comment 指出“返回值仅与分配的数量有关”,并且问题中引用的 C 标准文本可能旨在说“第一次分配”而不是“第一次转换” ”。

【讨论】:

  • 所以如果你需要知道字符是否被读取和抑制,你必须做sscanf("x","%n%*c%n%c",&n1,&n2,&chr),然后测试n1 != n2。请注意,您使用 &(char){0} 可能会导致错误,因为它会尝试写入只读段。
  • @SGeorgiades 你只需要在%*c 后面加上一个%n 并检查输出参数中的值是否为1。
  • @SGeorgiades 不是真的,函数范围内的复合文字是具有自动存储持续时间的左值 - C11§6.5.2.5p5 章。可以写信给它。
猜你喜欢
  • 2021-10-28
  • 1970-01-01
  • 2011-04-28
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2015-09-25
  • 2014-11-20
相关资源
最近更新 更多