snprintf and Visual Studio 2010

Solution 1:

Short story: Microsoft has finally implemented snprintf in Visual Studio 2015. On earlier versions you can simulate it as below.


Long version:

Here is the expected behavior for snprintf:

int snprintf( char* buffer, std::size_t buf_size, const char* format, ... );

Writes at most buf_size - 1 characters to a buffer. The resulting character string will be terminated with a null character, unless buf_size is zero. If buf_size is zero, nothing is written and buffer may be a null pointer. The return value is the number of characters that would have been written assuming unlimited buf_size, not counting the terminating null character.

Releases prior to Visual Studio 2015 didn't have a conformant implementation. There are instead non-standard extensions such as _snprintf() (which doesn't write null-terminator on overflow) and _snprintf_s() (which can enforce null-termination, but returns -1 on overflow instead of the number of characters that would have been written).

Suggested fallback for VS 2005 and up:

#if defined(_MSC_VER) && _MSC_VER < 1900

#define snprintf c99_snprintf
#define vsnprintf c99_vsnprintf

__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
    int count = -1;

    if (size != 0)
        count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
    if (count == -1)
        count = _vscprintf(format, ap);

    return count;
}

__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
{
    int count;
    va_list ap;

    va_start(ap, format);
    count = c99_vsnprintf(outBuf, size, format, ap);
    va_end(ap);

    return count;
}

#endif

Solution 2:

snprintf is not part of C89. It's standard only in C99. Microsoft has no plan supporting C99.

(But it's also standard in C++0x...!)

See other answers below for a workaround.

Solution 3:

If you don't need the return value, you could also just define snprintf as _snprintf_s

#define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__)

Solution 4:

I believe the Windows equivalent is sprintf_s

Solution 5:

Another safe replacement of snprintf() and vsnprintf() is provided by ffmpeg. You can checkout the source here (suggested).