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 );


A pointer to the buffer where you want to function to store the formatted string.
The maximum number of characters to store in the buffer, including a terminating null character.
A string that specifies the format of the output. The formatting string determines what additional arguments you need to provide. For more information, see printf().
A variable-argument list of the additional arguments, which you must have initialized with the va_start() macro.



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;


ANSI, POSIX 1003.1

Cancellation point No
Interrupt handler No
Signal handler Read the Caveats
Thread Yes


It's safe to call vsnprintf() in a signal handler if the data isn't floating point.

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), ...);