scanf是否保证不会在失败时更改值?

如果scanf系列函数无法与当前说明符匹配,是否允许写入存储成功值的存储?

在我的系统上,以下输出213两次但是有保证吗?

标准中的语言(C99或C11)似乎没有明确指出原始值应保持不变(无论它是否不确定)。

 #include  int main() { int d = 213; // matching failure sscanf("foo", "%d", &d); printf("%d\n", d); // input failure sscanf("", "%d", &d); printf("%d\n", d); } 

C11标准的相关部分是(7.21.6.2,对于fscanf):

7作为转换规范的指令定义了一组匹配的输入序列,如下面针对每个说明符所述。 转换规范按以下步骤执行:

8 […]

9除非规范包含n说明符,否则将从流中读取输入项。 输入项被定义为输入字符的最长序列,其不超过任何指定的字段宽度,并且是匹配输入序列的前缀,或者是匹配输入序列的前缀.285)输入项之后的第一个字符(如果有)仍未读。 如果输入项的长度为零,则指令的执行失败; 除非文件结束,编码错误或读取错误阻止了流的输入,否则此条件是匹配失败,在这种情况下,它是输入失败。

10除了%说明符之外,输入项(或者,在%n指令的情况下,输入字符的数量)将转换为适合转换说明符的类型。 如果输入项不是匹配序列,则指令的执行失败:此条件是匹配失败。 除非用*指示赋值抑制,否则转换的结果将放在由尚未收到转换结果的format参数后面的第一个参数指向的对象中。 […]

对我来说,单词“step”和“如果输入项的长度为零,指令的执行失败”表示如果输入与格式中的说明符不匹配,则解释在该说明符的任何赋值之前停止发生了。


另一方面,关于引用的子条款第4条清楚地表明,指定了失败的指定符,再次使用适用于有序事件序列的语言:

4 fscanf函数依次执行格式的每个指令。 当所有指令都已执行,或者指令失败时(如下所述),函数返回。

从ISO / IEC 9899:2011§7.21.6.2判断fscanffunction

¶10除了%说明符之外,输入项(或者,在%n指令的情况下,输入字符的数量)将转换为适合转换说明符的类型。 如果输入项不是匹配序列,则指令的执行失败:此条件是匹配失败。 除非用*指示赋值抑制,否则转换的结果将放在由尚未收到转换结果的format参数后面的第一个参数指向的对象中。 如果此对象没有适当的类型,或者无法在对象中表示转换结果,则行为未定义。

在更大的上下文中,这似乎意味着只有在转换成功后才会对目标变量进行赋值。 对于数字类型,这是有意义的,并且很容易实现。 对于字符串类型,它不是那么明确,但它应该以相同的方式工作(引用的文本表明只有在没有匹配的失败或输入失败时才会发生赋值)。 但是,如果在字符串( %s%30c%[az] )中存在编码错误,则即使转换整体失败,也会发现字符串的第一部分发生更改并不奇怪。 这可能被视为一个错误。 准确地刺激错误可能很难; 例如,它可能需要UTF-8输入和输入流中的无效字节,如0xC0或0xF5。