Is snprintf() ALWAYS null terminating?
Solution 1:
As the other answers establish: It should:
snprintf
... Writes the results to a character string buffer. (...) will be terminated with a null character, unless buf_size is zero.
So all you have to take care is that you don't pass an zero-size buffer to it, because (obviously) it cannot write a zero to "nowhere".
However, beware that Microsoft's library does not have a function called historically only had a function called snprintf
but instead_snprintf
(note leading underscore) which does not append a terminating null. Here's the docs (VS 2012, ~~ VS 2013):
http://msdn.microsoft.com/en-us/library/2ts7cx93%28v=vs.110%29.aspx
Return Value
Let len be the length of the formatted data string (not including the terminating null). len and count are in bytes for _snprintf, wide characters for _snwprintf.
If len < count, then len characters are stored in buffer, a null-terminator is appended, and len is returned.
If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned.
If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned.
(...)
Visual Studio 2015 (VC14) apparently introduced the conforming snprintf
function, but the legacy one with the leading underscore and the non null-terminating behavior is still there:
The
snprintf
function truncates the output when len is greater than or equal to count, by placing a null-terminator atbuffer[count-1]
. (...)For all functions other than
snprintf
, if len = count, len characters are stored in buffer, no null-terminator is appended, (...)
Solution 2:
According to snprintf(3) manpage.
The functions
snprintf()
andvsnprintf()
write at mostsize
bytes (including the trailing null byte ('\0')) tostr
.
So, yes, no need to terminate if size >= 1.
Solution 3:
According to the C standard, unless the buffer size is 0, vsnprintf()
and snprintf()
null terminates its output.
The
snprintf()
function shall be equivalent tosprintf()
, with the addition of the n argument which states the size of the buffer referred to by s. If n is zero, nothing shall be written and s may be a null pointer. Otherwise, output bytes beyond the n-1st shall be discarded instead of being written to the array, and a null byte is written at the end of the bytes actually written into the array.
So, if you need to know how big a buffer to allocate, use a size of zero, and you can then use a null pointer as the destination. Note that I linked to the POSIX pages, but these explicitly say that there is not intended to be any divergence between Standard C and POSIX where they cover the same ground:
The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2008 defers to the ISO C standard.
Be wary of the Microsoft version of vsnprintf()
. It definitely behaves differently from the standard C version when there is not enough space in the buffer (it returns -1 where the standard function returns the required length). It is not entirely clear that the Microsoft version null terminates its output under error conditions, whereas the standard C version does.
Note also the answers to Do you use the TR 24731 safe functions? (see MSDN for the Microsoft version of the vsprintf_s()
) and Mac solution for the safe alternatives to unsafe C standard library functions?