Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is `sscanf` guaranteed not to change arguments that it doesn't find?

Tags:

c

scanf

I have a case where I'm not sure if I'll get enough input for sscanf. Can I safely assume that sscanf won't mess with any argument that it doesn't find?

For example, in this program:

#include <stdio.h>

int main(int argc, char** argv) {
    int a = 0, b = 0, c = 0;
    sscanf("1 2", "%d %d %d", &a, &b, &c);
    printf("%d %d %d\n", a, b, c);
    return 0;
}

The output is:

1 2 0

So, it read two of the three numbers, and didn't mess with the last one. Can I safely assume that all compilers and standard libraries will also leave the last argument alone in this case, or do I need to do something like this:

int main(int argc, char** argv) {
    int a = 0, b = 0, c = 0;
    if (sscanf("1 2", "%d %d %d", &a, &b, &c) != 3) {
        c = 0;
    }
    printf("%d %d %d\n", a, b, c);
    return 0;
}
like image 348
Brendan Long Avatar asked Sep 17 '13 20:09

Brendan Long


3 Answers

You are completely safe.

In C11, 7.21.6.7 The sscanf function

2. ...Reaching the end of the string is equivalent to encountering end-of-file for the fscanf function.

7.21.6.2 The fscanf function says,

4. The fscanf function executes each directive of the format in turn. When all directives have been executed, or if a directive fails (as detailed below), the function returns. Failures are described as input failures (due to the occurrence of an encoding error or the unavailability of input characters), or matching failures (due to inappropriate input).

16. The fscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed.Otherwise, the function returns the number of input items assigned.

Your case is an input failure.

like image 86
srkrish Avatar answered Oct 07 '22 04:10

srkrish


From http://pubs.opengroup.org/onlinepubs/009695399/functions/scanf.html:

... If the format is exhausted while arguments remain, the excess arguments shall be evaluated but otherwise ignored.

Edit: As Kerrek correctly noticed, the above statement does not apply here. It is about sscanf("1", "%d", &a, &b, &c), and not about sscanf("1", "%d %d %d", &a, &b, &c) as in the question.

like image 24
Martin R Avatar answered Oct 07 '22 02:10

Martin R


The only reference I can find in C11 is for fscanf, 7.21.6.2/10, which says:

the result of the conversion is placed in the object pointed to by the first argument following the format argument that has not already received a conversion result.

I interpret "is placed in" as "is assigned to", and I'd say with reasonable confidence that this means that an assignment happens if and only if there's a match, otherwise the recipient variable isn't touched.

Note that all of the variable argument are evaluated before the function call, of course; this has nothing to do with scanf.

like image 43
Kerrek SB Avatar answered Oct 07 '22 02:10

Kerrek SB