5

我有一个案例,我不确定是否能获得足够的输入sscanf。我可以安全地假设它sscanf不会与它找不到的任何论点混淆吗?

例如,在这个程序中:

#include <stdio.h>

int main(int argc, char** argv) {
    int a = 0, b = 0, c = 0;
    sscanf("1 2", "%d %d %d", &a, &b, &c);
    printf("%d %d %d\n", a, b, c);
    return 0;
}

输出是:

1 2 0

因此,它读取了三个数字中的两个,并且没有与最后一个混淆。在这种情况下,我可以安全地假设所有编译器和标准库也会单独留下最后一个参数,还是我需要做这样的事情:

int main(int argc, char** argv) {
    int a = 0, b = 0, c = 0;
    if (sscanf("1 2", "%d %d %d", &a, &b, &c) != 3) {
        c = 0;
    }
    printf("%d %d %d\n", a, b, c);
    return 0;
}
4

5 回答 5

4

来自http://pubs.opengroup.org/onlinepubs/009695399/functions/scanf.html

...如果格式已用尽而参数仍然存在,则应评估多余的参数,否则将被忽略。

编辑:正如Kerrek 正确注意到的那样,上述声明不适用于此处。它是关于sscanf("1", "%d", &a, &b, &c),而不是 sscanf("1", "%d %d %d", &a, &b, &c)问题中的关于。

于 2013-09-17T20:08:56.070 回答
4

你是完全安全的。

在 C11 中,7.21.6.7 sscanf 函数

2. ...到达字符串的末尾相当于遇到 fscanf 函数的文件结尾。

7.21.6.2 fscanf 函数说,

4. fscanf函数依次执行格式的各个指令。当所有指令都已执行,或者如果指令失败(如下详述),函数返回。失败被描述为输入失败(由于发生编码错误或输入字符不可用)或匹配失败(由于输入不当)。

16. 如果在第一次转换(如果有)完成之前发生输入失败,则 fscanf 函数返回宏 EOF 的值。否则,该函数返回分配的输入项数。

你的情况是输入失败。

于 2013-09-17T21:00:27.113 回答
3

我在 C11 中可以找到的唯一参考是 for fscanf7.21.6.2/10,它说:

转换结果放置在格式参数后面的第一个参数所指向的对象中,该参数尚未收到转换结果。

我将“放置在”解释为“分配给”,并且我有理由相信这意味着当且仅当存在匹配时才会发生分配,否则不会触及接收者变量。

请注意,所有变量参数都在函数调用之前进行评估,当然;这无关scanf

于 2013-09-17T20:07:22.750 回答
3

7.21.6.2,第 21 段:

示例 4 在:

    #include <stdio.h>
    /* ... */
    int d1, d2, n1, n2, i;
    i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);

将值 123 分配给 d1,将值 3 分配给 n1。因为 %n 永远无法得到
一个输入失败,值 3 也赋给 n2。d2 的值不是
受影响。值 1 分配给 i。

这是我能找到的最接近的保证,即如果没有相应的输入可用,则不会修改参数。

于 2013-09-17T20:22:56.957 回答
1

保证。sscanf() 不会为额外的参数分配任何东西。您可以避免为此检查返回值

C 库函数 intsscanf(const char *str, const char *format, ...)从字符串读取格式化输入,而不是stdin

成功时,该函数返回参数列表中成功填充的项目数。

失败时,如果count can match the expected number of items or be less (even zero) in the case of a matching failure. 在成功解释任何数据之前输入失败,则返回 EOF。

如果转换规范的参数过多,则会评估额外的参数,否则会忽略。

如果没有足够的参数用于转换规范,则不会定义结果。

所有三个函数(fscanf, scanf, and sscanf) return都是成功匹配和分配的输入项的数量。返回值不包括已执行但未分配的转换(例如,抑制的分配)。

如果您检查项目数计数,在某些情况下可能会变为错误。

于 2013-09-17T20:22:08.523 回答