Search code examples
clinuxcurllibcurlglibc

Using GlibC, what is the analog of _snscanf() from Windows?


I have started going through the samples of the cURL, in C. While compiling ftpuploadresume.c I am getting undefined reference error at:

/* _snscanf() is Win32 specific */
r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);

I just want to know what is the alternative to _snscanf for glibc.


Solution

  • Assuming you use null terminated strings, you can perfectly safely use sscanf() without the second (length) argument. You could on Windows, too. If you don't know that the string is null terminated but you do know how long it is, add the null terminator. (If you don't know how long the string is and don't know whether it is null terminated, nothing is safe!)

    Assuming you have a C99 compiler, you can work the necessary change automatically:

    #define _snscanf(data, length, format, ...) scanf(data, format, __VA_ARGS__)
    

    Beware!

    Note the comment by namey — for which, thanks.

    Look at the Microsoft man pages on _snscanf(). The examples are not compelling; you'd get the same results even without the length being specified. However, it does look as though @namey is correct in general. A lot is going to depend on the context in which it is used. If the length specified is actually strlen(data), then the difference isn't going to matter. If the length specified is longer than that, the difference probably isn't going to matter. If the length is smaller than the length of the data, the difference might matter quite a lot.

    A better cover function might be:

    int _snscanf(const char *input, size_t length, const char *format, ...)
    {
        char *copy = malloc(length + 1);
        if (copy == 0)
            return 0;
        memmove(copy, input, length);
        copy[length] = '\0';
        va_list args;
        va_start(args, format);
        int rc = vsscanf(copy, format, args);
        va_end(args);
        free(copy);
        return rc;
    }