Updated: April 19, 2023 |
Write formatted output to a character array, up to a maximum number of characters (varargs)
#include <stdarg.h> #include <stdio.h> int vsnprintf( char* buf, size_t count, const char* format, va_list arg );
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
The vsnprintf() function formats data under control of the format control string and stores the result in buf. The maximum number of characters to store, including a terminating null character, is specified by count.
The vsnprintf() function is a varargs version of snprintf().
The number of characters that would have been written into the array, not counting the terminating null character, had count been large enough. It does this even if count is zero; in this case buf can be NULL.
If an error occurred, vsnprintf() returns a negative value and sets errno.
Use vsnprintf() in a general error message routine:
#include <stdio.h> #include <stdarg.h> #include <string.h> char msgbuf[80]; char *fmtmsg( char *format, ... ) { va_list arglist; va_start( arglist, format ); strcpy( msgbuf, "Error: " ); vsnprintf( &msgbuf[7], 80-7, format, arglist ); va_end( arglist ); return( msgbuf ); } int main( void ) { char *msg; msg = fmtmsg( "%s %d %s", "Failed", 100, "times" ); printf( "%s\n", msg ); return 0; }
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | Yes |
Signal handler | Yes |
Thread | Yes |
Be careful if you're using vsnprintf() to build a string one piece at a time. For example, this code:
len += vsnprintf(&buf[len], RECSIZE - 1 - len, ...);
could have a problem if vsnprintf() truncates the string. Without a separate test to compare len with RECSIZE, this code doesn't protect against a buffer overflow. After the call that truncates the output, len is larger than RECSIZE, and RECSIZE - 1 - len is a very large (unsigned) number; the next call generates unlimited output somewhere beyond the buffer. It's better to use something like this:
len += vsnprintf(&buf[len], (len >= RECSIZE ? 0 : RECSIZE - 1 - len), ...);