Is a NULL
pointer allowed as the string to store result in in a call to sscanf
? I don't find anything about it in any documentation but it seems to be working fine. Same thing with scanf
.
Example:
int main(int arc, char* argv[])
{
char* s = NULL;
sscanf("Privjet mir!", "%s", s);
printf("s: %s\n", s);
return 0;
}
Output: s: (null)
No terminating null is added. Pointer to char large enough for input field. Like c , a sequence of bytes of type char (signed or unsigned), except that white space characters are not allowed, and a terminating null is always added.
You are correct: sscanf indeed does not "move", because there is nothing to move. If you need to scan a bunch of ints, you can use strtol - it tells you how much it read, so you can feed the next pointer back to the function on the next iteration.
When we use the %n specifier in scanf() it will assign the number of characters read by the scanf() function until it occurs. Key points: It is an edit conversion code.
each of the sscanfs will call strlen once, but each strlen will scan the full remaining huge string to find the \0 eos byte. the sum of all scanned bytes is quadratic to the length of the huge input string.
No:
Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null character ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.
(http://linux.die.net/man/3/sscanf)
As is mentioned by the other answers NULL
is not valid to pass to sscanf
as an additional argument.
http://www.cplusplus.com/reference/cstdio/sscanf says of additional arguments:
Depending on the format string, the function may expect a sequence of additional arguments, each containing a pointer to allocated storage where the interpretation of the extracted characters is stored with the appropriate type.
For the %s
specifier these extracted characters are:
Any number of non-whitespace characters, stopping at the first whitespace character found. A terminating null character is automatically added at the end of the stored sequence.
So when the "non-whitespace characters" and "terminating null character" is stored, there will be a segfault. Which is exactly what Visual Studio will yield (you can test that this fails at http://webcompiler.cloudapp.net/):
Now as far as non-Visual Studio compilers, libc's extraction code for the %s
specifier: https://github.com/ffainelli/uClibc/blob/master/libc/stdio/_scanf.c#L1376 has the leading comment: /* We might have to handle the allocation ourselves */
this is because:
The GNU C library supported the dynamic allocation conversion specifier (as a nonstandard extension) via the
a
character. This feature seems to be present at least as far back as glibc 2.0.
Since version 2.7, glibc also provides them
modifier for the same purpose as thea
modifier.
[Source]
So because libc extracts to a buffer constructed internally to sscanf
and subsequently checks that the buffer parameter has no flags set before assigning it, it will never write characters to a NULL
buffer parameter.
I can't stress enough that this is non-standard, and is not guaranteed to be preserved even between minor library updates. A far better way to do this is to use the *
sub-specifier which:
Indicates that the data is to be read from the stream but ignored (i.e. it is not stored in the location pointed by an argument).
[Source]
This could be accomplished like this for example:
s == NULL ? sscanf("Privjet mir!", "%*s") : sscanf("Privjet mir!", "%s", s);
Obviously the true-branch of the ternary is a no-op, but I've included it with the expectation that other data was expected to be read from the string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With