_snprintf_s
, _snprintf_s_l
, _snwprintf_s
, _snwprintf_s_l
Writes formatted data to a string. These functions are versions of snprintf
, _snprintf
, _snprintf_l
, _snwprintf
, _snwprintf_l
with security enhancements described in Security features in the CRT.
Syntax
int _snprintf_s(
char *buffer,
size_t sizeOfBuffer,
size_t count,
const char *format [,
argument] ...
);
int _snprintf_s_l(
char *buffer,
size_t sizeOfBuffer,
size_t count,
const char *format,
_locale_t locale [,
argument] ...
);
int _snwprintf_s(
wchar_t *buffer,
size_t sizeOfBuffer,
size_t count,
const wchar_t *format [,
argument] ...
);
int _snwprintf_s_l(
wchar_t *buffer,
size_t sizeOfBuffer,
size_t count,
const wchar_t *format,
_locale_t locale [,
argument] ...
);
template <size_t size>
int _snprintf_s(
char (&buffer)[size],
size_t count,
const char *format [,
argument] ...
); // C++ only
template <size_t size>
int _snwprintf_s(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format [,
argument] ...
); // C++ only
Parameters
buffer
Storage location for the output.
sizeOfBuffer
The size of the storage location for output. Size in bytes for the functions that take char
, and words for those that take wchar_t
.
count
Maximum number of characters to write. For the functions that take wchar_t
, it's the maximum number of wide characters to write. Or _TRUNCATE
.
format
Format-control string.
argument
Optional arguments.
locale
The locale to use.
Return value
The number of characters written, not including the terminating NULL
. A negative value is returned if an output error occurs. See Behavior summary for details.
Remarks
The _snprintf_s
function formats and stores count
or fewer characters in buffer
and appends a terminating NULL
. Each argument (if any) is converted and output according to the corresponding format specification in format
. The formatting is consistent with the printf
family of functions; see Format specification syntax: printf
and wprintf
functions. If copying occurs between strings that overlap, the behavior is undefined.
Behavior summary
For the following table:
-Let len
be the size of the formatted data. If the function takes a char
buffer, the size is in bytes. If the function takes a wchar_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, not including the terminating NULL . |
N/A | No |
Encoding error during formatting | If processing string specifier s , S , or Z , format specification processing stops. |
-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 sizeOfBuffer == 0 and count == 0 |
No data is written. | 0 | N/A | No |
buffer == NULL and either sizeOfBuffer != 0 or count != 0 |
If execution continues after invalid parameter handler executes, sets errno and returns a negative value. |
-1 | EINVAL (22) |
Yes |
buffer != NULL and sizeOfBuffer == 0 |
No data is written. | -1 | EINVAL (22) |
Yes |
count == 0 |
A NULL is placed at the beginning of the buffer. |
-1 | 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, not including the terminating NULL . |
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. | N/A | No |
count < sizeOfBuffer and len > count |
The first count characters are written and a terminating NULL is appended. |
-1 | N/A | No |
count >= sizeOfBuffer and len < sizeOfBuffer |
All of the data is written with a terminating NULL . |
The number of characters written. | N/A | No |
count >= sizeOfBuffer and len >= sizeOfBuffer and count != _TRUNCATE |
If execution continues after invalid parameter handler executes, sets errno , sets buffer[0] == NULL , and returns a negative value. |
-1 | ERANGE (34) |
Yes |
count == _TRUNCATE and len >= sizeOfBuffer |
Writes as much of the string as fits in buffer and a terminating NULL . |
-1 | N/A | No |
count == _TRUNCATE and len < sizeOfBuffer |
Writes the entire string into buffer with a terminating NULL . |
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.
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_s
is a wide-character version of _snprintf_s
; the pointer arguments to _snwprintf_s
are wide-character strings. Detection of encoding errors in _snwprintf_s
might differ from that in _snprintf_s
. _snwprintf_s
, like swprintf_s
, writes output to a string rather than to a destination of type FILE
.
The versions of these functions with the _l
suffix are identical except that they use the locale parameter passed in instead of the current thread locale.
In C++, using these functions is simplified by template overloads; the overloads can infer buffer length automatically (eliminating the need to specify a size argument) and they can automatically replace older, non-secure functions with their newer, 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_s |
_snprintf_s |
_snprintf_s |
_snwprintf_s |
_sntprintf_s_l |
_snprintf_s_l |
_snprintf_s_l |
_snwprintf_s_l |
Requirements
Routine | Required header |
---|---|
_snprintf_s , _snprintf_s_l |
<stdio.h> |
_snwprintf_s , _snwprintf_s_l |
<stdio.h> or <wchar.h> |
For more compatibility information, see Compatibility.
Example
// crt_snprintf_s.cpp
// compile with: /MTd
// These #defines enable secure template overloads
// (see last part of Examples() below)
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crtdbg.h> // For _CrtSetReportMode
#include <errno.h>
// This example uses a 10-byte destination buffer.
int snprintf_s_tester( const char * fmt, int x, size_t count )
{
char dest[10];
printf( "\n" );
if ( count == _TRUNCATE )
printf( "%zd-byte buffer; truncation semantics\n",
_countof(dest) );
else
printf( "count = %zd; %zd-byte buffer\n",
count, _countof(dest) );
int ret = _snprintf_s( dest, _countof(dest), count, fmt, x );
printf( " new contents of dest: '%s'\n", dest );
return ret;
}
void Examples()
{
// formatted output string is 9 characters long: "<<<123>>>"
snprintf_s_tester( "<<<%d>>>", 121, 8 );
snprintf_s_tester( "<<<%d>>>", 121, 9 );
snprintf_s_tester( "<<<%d>>>", 121, 10 );
printf( "\nDestination buffer too small:\n" );
snprintf_s_tester( "<<<%d>>>", 1221, 10 );
printf( "\nTruncation examples:\n" );
int ret = snprintf_s_tester( "<<<%d>>>", 1221, _TRUNCATE );
printf( " truncation %s occur\n", ret == -1 ? "did"
: "did not" );
ret = snprintf_s_tester( "<<<%d>>>", 121, _TRUNCATE );
printf( " truncation %s occur\n", ret == -1 ? "did"
: "did not" );
printf( "\nSecure template overload example:\n" );
char dest[10];
_snprintf( dest, 10, "<<<%d>>>", 12321 );
// With secure template overloads enabled (see #defines
// at top of file), the preceding line is replaced by
// _snprintf_s( dest, _countof(dest), 10, "<<<%d>>>", 12345 );
// Instead of causing a buffer overrun, _snprintf_s invokes
// the invalid parameter handler.
// If secure template overloads were disabled, _snprintf would
// write 10 characters and overrun the dest buffer.
printf( " new contents of dest: '%s'\n", dest );
}
void myInvalidParameterHandler(
const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
wprintf(L"Invalid parameter handler invoked: %s\n", expression);
}
int main( void )
{
_invalid_parameter_handler oldHandler, newHandler;
newHandler = myInvalidParameterHandler;
oldHandler = _set_invalid_parameter_handler(newHandler);
// Disable the message box for assertions.
_CrtSetReportMode(_CRT_ASSERT, 0);
Examples();
}
count = 8; 10-byte buffer
new contents of dest: '<<<121>>'
count = 9; 10-byte buffer
new contents of dest: '<<<121>>>'
count = 10; 10-byte buffer
new contents of dest: '<<<121>>>'
Destination buffer too small:
count = 10; 10-byte buffer
Invalid parameter handler invoked: ("Buffer too small", 0)
new contents of dest: ''
Truncation examples:
10-byte buffer; truncation semantics
new contents of dest: '<<<1221>>'
truncation did occur
10-byte buffer; truncation semantics
new contents of dest: '<<<121>>>'
truncation did not occur
Secure template overload example:
Invalid parameter handler invoked: ("Buffer too small", 0)
new contents of dest: ''
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