如果某行与[fsv] scanf格式不匹配,scanf是否保证不会触及提供的不匹配指针?
例如,如果
int int1 = 3;
int int2 = 5;
sscanf(line, "%d %d", &int1, &int2);
返回0,保证仍然是3和5的整数,还是int1已被更改?
答案 0 :(得分: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);
将值
123
分配给d1
,将值3
分配给n1
。由于%n
永远无法获得输入失败,因此3
的值也会分配给n2
。d2
的值不受影响。值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。