I am using GCC 4.8 and glibc 2.19 on an x86_64 Linux.
While playing with different input methods for a different question, I compared fscanf
and s
sscanf() converts the string you pass in to an _IO_FILE*
to make the string look like a "file". This is so the same internal _IO_vfscanf() can be used for both a string and a FILE*.
However, as part of that conversion, done in a _IO_str_init_static_internal() function, it calls __rawmemchr (ptr, '\0');
essentially a strlen() call, on your input string. This conversion is done on every call to sscanf(), and since your input buffer is rather large, it'll spend a fair amount of time calculating the length of the input string.
Creating a FILE* from the input string using fmemopen() and use fscanf() could be another alternative.
It looks like glibc's sscanf()
scans the source string for the length before doing anything else.
sscanf()
(in stdio-common/sscanf.c
) is essentially a wrapper around a call to _IO_vsscanf()
(in libio/iovsscanf.c
). And one of the first things that _IO_vsscanf()
does is initialize its own _IO_strfile
structure by calling _IO_str_init_static_internal()
(in libio/strops.c
) which calculates the length of the string if it's not provided.