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

时间:2014-09-29 10:15:48

标签: c scanf

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

例如,如果

int int1 = 3;
int int2 = 5;
sscanf(line, "%d %d", &int1, &int2);

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

2 个答案:

答案 0 :(得分:5)

简短的回答是是的,在您的情况下,您可以保证int1int2没有改变

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


答案很长取决于您的格式字符串。查看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);
     

将值123分配给d1,将值3分配给n1。由于%n永远无法获得输入失败,因此3的值也会分配给n2d2的值不受影响。值1已分配给i

如果你不熟悉%n,那就是“到目前为止从流中读取的字符数”。

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

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

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

sscanf("aaa","aaa%n%d",&n1,&n2);

这会将3写入n1,保持n2不变,然后返回EOF。和

sscanf("aaa bbb","aaa%n%d",&n1,&n2);

这会将3写入n1,保持n2不变,然后返回0.

答案 1 :(得分:0)

这些参数应该至少与sscanf的格式说明符存储的值的数量一样多。 sscanf函数忽略了其他参数。 如果line包含say&#34; 10 20&#34 ;,则int1和int2将分别更改为10和20。 但是,如果line包含say&#34; aa bb&#34 ;,则int1和int2将分别保留为3和5。