如果一行与[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已被更改?
简短的回答是肯定的,在您的情况下,您可以保证int1并且int2没有改变.
但是,我建议不要依赖这种行为,因为它可能会产生难以阅读的代码 - 并且因为:
答案很长,这取决于你的格式字符串.看一下fscanf(s7.21.6.2.16)的C11标准,我们有:
如果在第一次转换(如果有)完成之前发生输入故障,fscanf函数将返回宏EOF的值.否则,该函数返回分配的输入项的数量,如果早期匹配失败,则可以少于提供的数量,甚至为零.
非常重要的是7.21.6.2中后面的输入项定义:
输入项被定义为输入字符的最长序列,其不超过任何指定的字段宽度,并且是匹配的输入序列的前缀或前缀.
所以.scanf返回的数字是从流中读取的项目数,而不是写入的指针数.
另外相关的是7.21.6.2.2:
如果参数保留时格式已用尽,则会评估多余的参数(一如既往),否则将被忽略.
忽略未写入的参数的行为也在该部分末尾的示例中显式化:
在:
Run Code Online (Sandbox Code Playgroud)#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);
Run Code Online (Sandbox Code Playgroud)
这写3来n1,叶n2不变,并返回EOF.和:
sscanf("aaa bbb","aaa%n%d",&n1,&n2);
Run Code Online (Sandbox Code Playgroud)
这写3来n1,叶n2不变,并返回0.