tags:

views:

41

answers:

1

I've been trying to get sscanf to recognize a fairly simple format using character classes. I've noticed that when I provide sscanf with a char* to match the character class it overwrites the previous byte also as if it expected a pointer to 2 bytes.

A simplified version of what I'm trying to accomplish:

#include <stdio.h>

int main(void)
{
    char num1;
    char num2;
    int s;
    s = sscanf("1,2", " %[01234567] , %[01234567]", &num1, &num2);
    printf("%d %c %c\n", s, num1, num2);
    return 0;
}

Expected output: 2 1 2

Actual output: 2 2

But if I replace char with short (or something else greater than a byte) then it works as expected, but I get warnings about format expects type char*.

What type should the argument actually be or am I making some other error?

+2  A: 

sscanf expects a string.

char num1[BIG_ENOUGH], num2[BIG_ENOUGH];
s = sscanf("1,2", " %[01234567] , %[01234567]", num1, num2);

Of course this is completely unsafe, as the scanned string plus the terminating null may be longer than the buffer and cause a buffer overflow.

Unfortunately, the C type system can't differentiate between pointer to the beginning of a character array and a pointer to a single character, so the code in the question compiled.

Amnon
Isn't it a bug in `sscanf` implementation? According to the [documentation](http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/), for `%c` "no null character is appended at the end." I didn't however find any documentation describing `%[...]`-like arguments.
Vlad
I found the needed documentation: http://linux.die.net/man/3/scanf. It says that "the next pointer must be a pointer to char, and there must be enough room for all the characters in the string, **plus a terminating null byte**," which explains the behaviour.
Vlad