c++stringformat-specifiers

Scan the string from white space until end using format specifier


I have an existing code that scans a string and stores values in multiple temporary variables.

Here is the sample code:

char str[] = "# # Time=80 interval";
char hash1, hash2;
char timeStr[20];

sscanf(str, "%c %c %[^\0]s", &hash1, &hash2, timeStr);

printf("hash 1: %c\n", hash1);
printf("hash 2: %c\n", hash2);
printf("Time String: %s\n", timeStr);

Actual output is:

hash 1: #
hash 2: #
Time String: 

The expected output is:

hash 1: #
hash 2: #
Time String: Time=80 interval

I modified the code and it is working:

sscanf(str, "%c %c **%[^\n]s**", &hash1, &hash2, timeStr);

This is legacy code %[^\0]s and it is not working now.

Can someone help to understand by any chance why it was working earlier and stopped working now?


Solution

  • In this string literal you've embedded a \0:

    "%c %c %[^\0]s"
    

    What the scanf function will see is everything up to the \0, so it sees the format string

    "%c %c %[^"
    

    Some compilers may even complain about it and say "no closing ']' for '%[' format".

    Furthermore, %[^\n]s should be just %[^\n]. %[...] and %s are different conversion specifiers. Also, always check the return value from scanf.

    Can someone help to understand by any chance why it was working earlier and stopped working now?

    The earlier compiler presumably treated the non-terminated %[^ sequence as %[^\0] to allow for mistakes like this, in which case you could probably just have used "%c %c %[^" with the old compiler. The new compiler does not support this extension.