If a scanf
family function fails to match the current specifier, is it permitted to write to the storage where it would have stored the value on success?
On my system the following outputs 213
twice but is that guaranteed?
The language in the standard (C99 or C11) does not seem to clearly specify that the original value should remain unchanged (whether it was indeterminate or not).
#include <stdio.h>
int main()
{
int d = 213;
// matching failure
sscanf("foo", "%d", &d);
printf("%d\n", d);
// input failure
sscanf("", "%d", &d);
printf("%d\n", d);
}
Judging from ISO/IEC 9899:2011 §7.21.6.2 The
fscanf
function:In the larger context, this seems to mean that the assignment to the target variable only occurs after the conversion is successful. For numeric types, that makes sense and is readily achievable. For string types, it is not so clear cut, but it should work the same way (the text quoted does state that the assignment only occurs if there is no matching failure or input failure). However, if there is an encoding error part way through a string (
%s
or%30c
or%[a-z]
), it would not be surprising to find that the first part of the string is changed even though the conversion as a whole failed. This could probably be regarded as a bug. Stimulating the bug accurately might be hard; for example, it might require UTF-8 input and an invalid byte such as 0xC0 or 0xF5 in the input stream.The relevant part of the C11 standard is (7.21.6.2, for fscanf):
To me, the words “step” and “If the length of the input item is zero, the execution of the directive fail” indicate that if the input does not match a specifier in the format, interpretation stops before any assignment for that specifier has occurred.
On the other hand, the subclause 4 about the ones quoted makes it clear that specifiers up to the failing one are assigned, again using language appropriate for ordered sequences of events: