snprintf
, _snprintf
, _snprintf_l
, _snwprintf
, _snwprintf_l
Writes formatted data to a string. More secure versions of these functions are available; see _snprintf_s
, _snprintf_s_l
, _snwprintf_s
, _snwprintf_s_l
.
Syntax
int snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...
);
int _snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...
);
int _snprintf_l(
char *buffer,
size_t count,
const char *format,
_locale_t locale [,
argument] ...
);
int _snwprintf(
wchar_t *buffer,
size_t count,
const wchar_t *format [,
argument] ...
);
int _snwprintf_l(
wchar_t *buffer,
size_t count,
const wchar_t *format,
_locale_t locale [,
argument] ...
);
template <size_t size>
int _snprintf(
char (&buffer)[size],
size_t count,
const char *format [,
argument] ...
); // C++ only
template <size_t size>
int _snprintf_l(
char (&buffer)[size],
size_t count,
const char *format,
_locale_t locale [,
argument] ...
); // C++ only
template <size_t size>
int _snwprintf(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format [,
argument] ...
); // C++ only
template <size_t size>
int _snwprintf_l(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format,
_locale_t locale [,
argument] ...
); // C++ only
Parameters
buffer
Storage location for the output.
count
Maximum number of characters to write. For the functions that take wchar_t
, it's the maximum number of wide characters to write.
format
Format-control string.
argument
Optional arguments.
locale
The locale to use to format the output.
For more information, see Format specification syntax: printf
and wprintf
functions.
Return value
The number of characters that which would have been written to the buffer if count
was ignored. The count doesn't include the terminating NULL
character.
Let len
be the length of the formatted data string, not including the terminating NULL
.
For all functions, if len < count
, then len
characters are stored in buffer
, a null-terminator is appended, and the number of characters written, not including the terminating NULL
, is returned.
The wide character versions of these functions return the number of wide characters written, not including the terminating NULL
.
See Behavior summary for details.
Remarks
Beginning with the UCRT in Visual Studio 2015 and Windows 10, snprintf
is no longer identical to _snprintf
. The snprintf
behavior is now C99 standard conformant. The difference is that if you run out of buffer, snprintf
null-terminates the end of the buffer and returns the number of characters that would have been required whereas _snprintf
doesn't null-terminate the buffer and returns -1. Also, snprintf()
includes one more character in the output because it doesn't null-terminate the buffer.
snprintf
and the_snprintf
family of functions format and storecount
or fewer characters inbuffer
.snprintf
always stores a terminatingNULL
character, truncating the output if necessary.- If
snprintf
returns a value >count
- 1, the output has been truncated. - The
_snprintf
family of functions only appends a terminatingNULL
character if the formatted string length is strictly less thancount
characters. - Each
argument
(if any) is converted and is output according to the corresponding format specification informat
. The format consists of ordinary characters and has the same form and function as theformat
argument forprintf
. If copying occurs between strings that overlap, the behavior is undefined.
Behavior summary
For the following table:
- Let
sizeOfBuffer
be the size ofbuffer
. If the function takes achar
buffer, the size is in bytes. If the function takes awchar_t
buffer, the size specifies the number of 16-bit words. - Let
len
be the size of the formatted data. If the function takes achar
buffer, the size is in bytes. If the function takes awchar_t
buffer, the size specifies the number of 16-bit words. - Characters refer to
char
characters for functions that take achar
buffer, and towchar_t
characters for functions that take awchar_t
buffer. - For more information about the invalid parameter handler, see Parameter Validation.
Condition | Behavior | Return value | errno |
Invokes invalid parameter handler |
---|---|---|---|---|
Success | Writes the characters into the buffer using the specified format string. | The number of characters written. | N/A | No |
Encoding error during formatting | If processing string specifier s , S , or Z , format specification processing stops, a NULL is placed at the beginning of the buffer. |
-1 | EILSEQ (42) |
No |
Encoding error during formatting | If processing character specifier c or C , the invalid character is skipped. The number of characters written isn't incremented for the skipped character, nor is any data written for it. Processing the format specification continues after skipping the specifier with the encoding error. |
The number of characters written, not including the terminating NULL . |
EILSEQ (42) |
No |
buffer == NULL and count != 0 |
If execution continues after invalid parameter handler executes, sets errno and returns a negative value. |
-1 | EINVAL (22) |
Yes |
count == 0 |
The number of characters that would have been written, not including the terminating NULL . You can use this result to allocate sufficient buffer space for the string and a terminating NULL , and then call the function again to fill the buffer. |
N/A | No | |
count < 0 |
Unsafe: the value is treated as unsigned, likely creating a large value that results in overwriting the memory that follows the buffer. | The number of characters written | N/A | No |
count < sizeOfBuffer and len <= count |
All of the data is written and a terminating NULL is appended. |
The number of characters written, not including the terminating NULL . |
N/A | No |
count < sizeOfBuffer and len > count |
The first count-1 characters are written followed by a null-terminator. |
The number of characters that would have been written had count matched the number of characters to output, not including the null-terminator. |
N/A | No |
count >= sizeOfBuffer and len < sizeOfBuffer |
All of the data is written with a terminating NULL . |
The number of characters written, not including the terminating NULL . |
N/A | No |
count >= sizeOfBuffer and len >= sizeOfBuffer |
Unsafe: Overwrites the memory that follows the buffer. | The number of characters written, not including the terminating NULL . |
N/A | No |
format == NULL |
No data is written. If execution continues after invalid parameter handler executes, sets errno and returns a negative value. |
-1 | EINVAL (22) |
Yes |
For information about these and other error codes, see _doserrno
, errno
, _sys_errlist
, and _sys_nerr
.
Important
Ensure that format
is not a user-defined string. Because the _snprintf
functions do not guarantee null termination—in particular, when the return value is count
—make sure that they are followed by code that adds the null terminator. For more information, see Avoiding buffer overruns.
Starting in Windows 10 version 2004 (build 19041), the printf
family of functions prints exactly representable floating point numbers according to the IEEE 754 rules for rounding. In previous versions of Windows, exactly representable floating point numbers ending in '5' would always round up. IEEE 754 states that they must round to the closest even digit (also known as "Banker's Rounding"). For example, both printf("%1.0f", 1.5)
and printf("%1.0f", 2.5)
should round to 2. Previously, 1.5 would round to 2 and 2.5 would round to 3. This change only affects exactly representable numbers. For example, 2.35 (which, when represented in memory, is closer to 2.35000000000000008) continues to round up to 2.4. Rounding done by these functions now also respects the floating point rounding mode set by fesetround
. Previously, rounding always chose FE_TONEAREST
behavior. This change only affects programs built using Visual Studio 2019 version 16.2 and later. To use the legacy floating point rounding behavior, link with legacy_stdio_float_rounding.obj
.
_snwprintf
is a wide-character version of _snprintf
; the pointer arguments to _snwprintf
are wide-character strings. Detection of encoding errors in _snwprintf
might differ from the detection in _snprintf
. _snwprintf
, just like swprintf
, writes output to a string instead of a destination of type FILE
.
The versions of these functions that have the _l
suffix are identical except that they use the locale parameter passed in instead of the current thread locale.
In C++, these functions have template overloads that invoke the newer, more secure counterparts. For more information, see Secure template overloads.
Generic-text routine mappings
Tchar.h routine |
_UNICODE and _MBCS not defined |
_MBCS defined |
_UNICODE defined |
---|---|---|---|
_sntprintf |
_snprintf |
_snprintf |
_snwprintf |
_sntprintf_l |
_snprintf_l |
_snprintf_l |
_snwprintf_l |
Requirements
Routine | Required header |
---|---|
snprintf , _snprintf , _snprintf_l |
<stdio.h> |
_snwprintf , _snwprintf_l |
<stdio.h> or <wchar.h> |
For more compatibility information, see Compatibility.
Example
// crt_snprintf.c
// compile with: /W3
#include <stdio.h>
#include <stdlib.h>
#if !defined(__cplusplus)
typedef int bool;
const bool true = 1;
const bool false = 0;
#endif
#define FAIL 0 // change to 1 and see what happens
int main(void)
{
char buffer[200];
const static char s[] = "computer"
#if FAIL
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
#endif
;
const char c = 'l';
const int i = 35;
#if FAIL
const double fp = 1e300; // doesn't fit in the buffer
#else
const double fp = 1.7320534;
#endif
/* !subtract one to prevent "squeezing out" the terminal null! */
const int bufferSize = sizeof(buffer)/sizeof(buffer[0]) - 1;
int bufferUsed = 0;
int bufferLeft = bufferSize - bufferUsed;
bool bSuccess = true;
buffer[0] = 0;
/* Format and print various data: */
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
bufferLeft, " String: %s\n", s ); // C4996
// Note: _snprintf is deprecated; consider _snprintf_s instead
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
bufferLeft, " Character: %c\n", c ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer
[bufferUsed], bufferLeft, " Integer: %d\n", i ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer
[bufferUsed], bufferLeft, " Real: %f\n", fp ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
}
}
}
}
}
}
}
}
if (!bSuccess)
{
printf("%s\n", "failure");
}
else
{
/* !store null because _snprintf doesn't necessarily (if the string
* fits without the terminal null, but not with it)!
* bufferUsed might be as large as bufferSize, which normally is
* like going one element beyond a buffer, but in this case
* subtracted one from bufferSize, so we're ok.
*/
buffer[bufferUsed] = 0;
printf( "Output:\n%s\ncharacter count = %d\n", buffer, bufferUsed );
}
return EXIT_SUCCESS;
}
Output:
String: computer
Character: l
Integer: 35
Real: 1.732053
character count = 69
See also
Stream I/O
sprintf
, _sprintf_l
, swprintf
, _swprintf_l
, __swprintf_l
fprintf
, _fprintf_l
, fwprintf
, _fwprintf_l
printf
, _printf_l
, wprintf
, _wprintf_l
scanf
, _scanf_l
, wscanf
, _wscanf_l
sscanf
, _sscanf_l
, swscanf
, _swscanf_l
vprintf
functions