如果没有找到匹配项,sscanf会触摸指针吗?

Pet*_*mit 5 c scanf

如果一行与[fsv] scanf格式不匹配,scanf是否保证不接触提供的不匹配指针?

例如,如果

int int1 = 3;
int int2 = 5;
sscanf(line, "%d %d", &int1, &int2);
Run Code Online (Sandbox Code Playgroud)

返回0,保证仍然是3和5的整数,还是int1已被更改?

Tim*_*nes 5

简短的回答是肯定的,在您的情况下,您可以保证int1并且int2没有改变.

但是,我建议不要依赖这种行为,因为它可能会产生难以阅读的代码 - 并且因为:


答案很长,这取决于你的格式字符串.看一下fscanf(s7.21.6.2.16)的C11标准,我们有:

如果在第一次转换(如果有)完成之前发生输入故障,fscanf函数将返回宏EOF的值.否则,该函数返回分配的输入项的数量,如果早期匹配失败,则可以少于提供的数量,甚至为零.

非常重要的是7.21.6.2中后面的输入项定义:

输入项被定义为输入字符的最长序列,其不超过任何指定的字段宽度,并且是匹配的输入序列的前缀或前缀.

所以.scanf返回的数字是从流中读取的项目数,而不是写入的指针数.

另外相关的是7.21.6.2.2:

如果参数保留时格式已用尽,则会评估多余的参数(一如既往),否则将被忽略.

忽略未写入的参数的行为也在该部分末尾的示例中显式化:

在:

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

的值123被分配到d1和值3n1.因为%n永远不会得到输入失败,3所以也会赋值n2.价值d2不受影响.该值1已分配给i.

如果你不熟悉%n,它是"到目前为止从流中读取的字符数".

这是一个很好的例子来说明你的问题 - 这里我们有三个指针写入,一个指针未触及.但是,fscanf这里只返回1 - 因为它只从流中分配了一个"输入项".

所以,在你的例子中,是的,如果你已经得到%d %d并且你传递了导致0次读取的东西,那么是的,指针将不受影响.

但是,如果你有一个%n,那么你的函数仍然可以返回0或EOF,同时仍然消耗一些输入并写入指针.例如:

sscanf("aaa","aaa%n%d",&n1,&n2);
Run Code Online (Sandbox Code Playgroud)

这写3n1,叶n2不变,并返回EOF.和:

sscanf("aaa bbb","aaa%n%d",&n1,&n2);
Run Code Online (Sandbox Code Playgroud)

这写3n1,叶n2不变,并返回0.