Is scanf a guarantee that it will not change the value on error?

If the scanf family function does not match the current specifier, is it allowed to write to the repository where it would save the value upon successful completion?

On my system, the following outputs 213 twice, but is this guaranteed?

The language in the standard (C99 or C11) does not explicitly indicate that the original value should remain unchanged (regardless of whether it was undefined 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); } 
+6
source share
2 answers

Relevant part of C11 (7.21.6.2, for fscanf):

7 The directive, which is a conversion specification, defines a set of matching input sequences, as described below for each qualifier. The conversion specification is performed in the following steps:

eight [...]

9 An input element is read from the stream if the specification does not contain the qualifier n. An input element is defined as the longest sequence of input characters, which does not exceed the specified field width and which is or is a prefix of the corresponding input sequence .285) The first character, if any, remains unread after entering the element. If the length of the input element is zero, the directive fails; this condition is a coincident failure, if only the end of the file, encoding error or read error does not allow input from the stream, in which case it is an input failure.

10 Except in the case of the% specifier, the input element (or, in the case of the% n directive, the number of input characters) is converted to a type corresponding to the conversion specifier. If the input element does not match the sequence, the directive is not executed: this condition is a matching failure. If the assignment exception was not indicated by the * character, the conversion result is placed in the object pointed to by the first argument, following the format argument, which has not yet received the conversion result. [...]

For me, the words "step" and "If the length of the input element is zero, the directive fails" indicates that if the input does not match the qualifier in the format, the interpretation stops before this qualifier has occurred.


On the other hand, subparagraph 4 on quoted messages clearly states that qualifiers are assigned to failure, again using a language suitable for ordered sequences of events:

4 The fscanf function executes each format directive in turn. When all directives are executed or if the directive does not work (as described below), the function returns.

+5
source

Judging by ISO / IEC 9899: 2011 Β§7.21.6.2 fscanf function :

ΒΆ10 Except for the case of the % specifier, the input element (or, in the case of the %n directive, the number of input characters) is converted to the type corresponding to the conversion specifier. If the input element does not match the sequence, the directive is not executed: this condition is a corresponding failure. If there was no suppression of the a * assignment, the conversion result is placed in the object pointed to by the first argument, the next argument of the format that has not yet received the conversion result. If this object does not have the appropriate type or if the result of the conversion cannot be represented in the object, undefined behavior.

In a broader context, this means that the assignment of the target variable occurs only after a successful conversion. For numeric types, this makes sense and is easily achievable. For string types, this is not so clear, but it should work the same way (the cited text indicates that assignment occurs only in the absence of a corresponding failure or input failure). However, if a part of the encoding error passes through the string ( %s or %30c or %[az] ), it would not be surprising to find that the first part of the string changes even if the conversion as a whole could not. This can probably be considered a mistake. Fostering error can be difficult; for example, input may require UTF-8 input and an invalid byte, such as 0xC0 or 0xF5 in the input stream.

+3
source

Source: https://habr.com/ru/post/974948/


All Articles