【问题标题】:Shall converversion specifier "%%" match white spaces应转换说明符“%%”匹配空格
【发布时间】:2021-08-05 16:59:08
【问题描述】:

根据 C 标准,转换说明符 % 定义为:

% 匹配单个 % 字符;不会发生转换或分配。这 完整的转换规范应为 %%。

但是这段代码:

int main(int argc, char* argv[])
{
    int n;
    printf("%d\n", sscanf("     %123", "%% %d", &n));
    return 0;
}

使用 gcc-11.1.0 编译得到输出 1,因此 %% 显然与字符串的 " %" 匹配。

这似乎违反了“匹配单个 % 字符”,因为它还接受了 % 字符前面的空格。

问题:根据标准接受空格作为%% 指令的一部分是否正确?

【问题讨论】:

  • en.cppreference.com/w/c/io/fscanf: "除 [、c 和 n 之外的所有转换说明符都会消耗并丢弃所有前导空白字符"
  • @Mat 谢谢...这是我错过的标准部分

标签: c gcc language-lawyer


【解决方案1】:

根据 C89 标准,至少“跳过输入空白字符 [...],除非规范包含 [cn 说明符。” (这是标准的旧版本,但它是我得心应手的版本。但我不认为这在最近的版本中有所改变。)

【讨论】:

  • 谢谢 - 虽然这对我来说是众所周知的,例如%d single 这个词有点欺骗了我。这显然是正确的。
  • 这意味着它不匹配多个% 字符,而不是它只消耗输入中的单个字符。但这很容易引起误解。
  • @Clifford 我不这么认为。被解析的字符串是" %123";格式字符串为"%% %d"。在%d 可以看到123 之前,必须使用%
【解决方案2】:

我查看了final C17 draft,实际上有一个具体示例表明%% 跳过了空格:

示例 5 调用:

#include <stdio.h>
/* ... */
int n, i;
n = sscanf("foo %bar 42", "foo%%bar%d", &i);

将赋值给 n 值 1 和赋值给 i 值 42 因为输入 % 和 d 转换都跳过空白字符 说明符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 2020-04-13
    • 2018-01-16
    • 2012-06-30
    • 1970-01-01
    • 2018-06-22
    • 2020-09-13
    相关资源
    最近更新 更多