_snprintf_s
, , _snprintf_s_l
, , _snwprintf_s
_snwprintf_s_l
Zapisuje sformatowane dane do ciągu. Te funkcje to wersje , snprintf
, _snprintf_l
_snprintf
, _snwprintf
_snwprintf_l
, z ulepszeniami zabezpieczeń opisanymi w temacie Funkcje zabezpieczeń w języku CRT.
Składnia
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
Parametry
buffer
Lokalizacja w pamięci dla danych wyjściowych.
sizeOfBuffer
Rozmiar lokalizacji magazynu dla danych wyjściowych. Rozmiar w bajtach dla funkcji, które przyjmują char
, i wyrazy dla tych, które przyjmują wchar_t
.
count
Maksymalna liczba znaków do zapisu. W przypadku funkcji, które przyjmują wchar_t
wartość , jest to maksymalna liczba znaków do zapisania. Lub _TRUNCATE
.
format
Ciąg kontroli formatu.
argument
Argumenty opcjonalne.
locale
Ustawienia regionalne do użycia.
Wartość zwracana
Liczba zapisanych znaków, a nie łącznie z kończeniem NULL
. Wartość ujemna jest zwracana, jeśli wystąpi błąd wyjściowy. Aby uzyskać szczegółowe informacje, zobacz Podsumowanie zachowania.
Uwagi
Funkcja _snprintf_s
formatuje i przechowuje count
lub mniej znaków w buffer
pliku i dołącza terminację NULL
. Każdy argument (jeśli istnieje) jest konwertowany i wyjściowy zgodnie z odpowiednią specyfikacją formatu w pliku format
. Formatowanie jest zgodne z rodziną printf
funkcji. Zobacz Składnia specyfikacji formatu: printf
i wprintf
funkcje. Jeśli kopiowanie odbywa się między nakładającymi się ciągami, zachowanie jest niezdefiniowane.
Podsumowanie zachowania
W poniższej tabeli:
-Niech len
rozmiar sformatowanych danych. Jeśli funkcja przyjmuje char
bufor, rozmiar jest w bajtach. Jeśli funkcja przyjmuje wchar_t
bufor, rozmiar określa liczbę 16-bitowych wyrazów.
- Znaki odwołują się do
char
znaków funkcji, które przyjmująchar
bufor, oraz dowchar_t
znaków funkcji, które przyjmująwchar_t
bufor. - Aby uzyskać więcej informacji na temat nieprawidłowej procedury obsługi parametrów, zobacz Walidacja parametrów.
Stan | Zachowanie | Wartość zwracana | errno |
Wywołuje nieprawidłową procedurę obsługi parametrów |
---|---|---|---|---|
Powodzenie | Zapisuje znaki w buforze przy użyciu określonego ciągu formatu. | Liczba zapisanych znaków, a nie łącznie z kończeniem NULL . |
Nie dotyczy | Nie. |
Błąd kodowania podczas formatowania | Jeśli przetwarzanie specyfikatora s ciągów , S lub Z , przetwarzanie specyfikacji formatu zatrzymuje się. |
-1 | EILSEQ (42) |
Nie. |
Błąd kodowania podczas formatowania | Jeśli specyfikator c znaków przetwarzania lub C , jest pomijany nieprawidłowy znak. Liczba zapisanych znaków nie jest zwiększana dla pominiętego znaku ani żadnych zapisanych dla niego danych. Przetwarzanie specyfikacji formatu jest kontynuowane po pomijaniu specyfikatora z błędem kodowania. |
Liczba zapisanych znaków, a nie łącznie z kończeniem NULL . |
EILSEQ (42) |
Nie. |
buffer == NULL i i sizeOfBuffer == 0 count == 0 |
Żadne dane nie są zapisywane. | 0 | Nie dotyczy | Nie. |
buffer == NULL i albo sizeOfBuffer != 0 lub count != 0 |
Jeśli wykonanie będzie kontynuowane po wykonaniu nieprawidłowego programu obsługi parametrów, ustawia errno i zwraca wartość ujemną. |
-1 | EINVAL (22) |
Tak |
buffer != NULL i sizeOfBuffer == 0 |
Żadne dane nie są zapisywane. | -1 | EINVAL (22) |
Tak |
count == 0 |
Element A NULL znajduje się na początku buforu. |
-1 | Nie dotyczy | Nie. |
count < 0 |
Niebezpieczne: wartość jest traktowana jako niepodpisane, prawdopodobnie tworząc dużą wartość, która powoduje zastąpienie pamięci, która następuje po buforze. | Liczba zapisanych znaków, a nie łącznie z kończeniem NULL . |
Nie dotyczy | Nie. |
count < sizeOfBuffer i len <= count |
Wszystkie dane są zapisywane i dołączane są kończenie NULL . |
Liczba zapisanych znaków. | Nie dotyczy | Nie. |
count < sizeOfBuffer i len > count |
count Pierwsze znaki są zapisywane i dołączane jest kończenieNULL . |
-1 | Nie dotyczy | Nie. |
count >= sizeOfBuffer i len < sizeOfBuffer |
Wszystkie dane są zapisywane z kończeniem NULL . |
Liczba zapisanych znaków. | Nie dotyczy | Nie. |
count >= sizeOfBuffer i i len >= sizeOfBuffer count != _TRUNCATE |
Jeśli wykonanie będzie kontynuowane po wykonaniu nieprawidłowego programu obsługi parametrów, ustawia errno , ustawia buffer[0] == NULL wartości i zwraca wartość ujemną. |
-1 | ERANGE (34) |
Tak |
count == _TRUNCATE i len >= sizeOfBuffer |
Zapisuje tyle ciągów, jak pasuje do buffer i kończy ciąg NULL . |
-1 | Nie dotyczy | Nie. |
count == _TRUNCATE i len < sizeOfBuffer |
Zapisuje cały ciąg w buffer pliku z kończeniem NULL ciągu . |
Liczba zapisanych znaków, a nie łącznie z kończeniem NULL . |
Nie dotyczy | Nie. |
format == NULL |
Żadne dane nie są zapisywane. Jeśli wykonanie będzie kontynuowane po wykonaniu nieprawidłowego programu obsługi parametrów, ustawia errno i zwraca wartość ujemną. |
-1 | EINVAL (22) |
Tak |
Aby uzyskać informacje o tych i innych kodach błędów, zobacz _doserrno
, errno
, _sys_errlist
i _sys_nerr
.
Ważne
Upewnij się, że format
nie jest to ciąg zdefiniowany przez użytkownika.
Począwszy od systemu Windows 10 w wersji 2004 (kompilacja 19041), printf
rodzina funkcji drukuje dokładnie możliwe liczby zmiennoprzecinkowe zgodnie z regułami IEEE 754 dotyczącymi zaokrąglania. W poprzednich wersjach systemu Windows dokładnie reprezentowane liczby zmiennoprzecinkowe kończące się na "5" zawsze zaokrągla się w górę. IEEE 754 stwierdza, że muszą zaokrąglić do najbliższej parzysta cyfra (znana również jako "Zaokrąglanie Bankiera"). Na przykład oba printf("%1.0f", 1.5)
printf("%1.0f", 2.5)
elementy i powinny być zaokrąglone do 2. Wcześniej 1,5 zaokrągliłoby się do 2 i 2,5 do 3. Ta zmiana dotyczy tylko dokładnie możliwych do reprezentowania liczb. Na przykład 2,35 (który, gdy jest reprezentowany w pamięci, jest bliżej 2,350000000000000008) nadal zaokrągla się do 2,4. Zaokrąglanie wykonywane przez te funkcje jest teraz również zgodne z trybem zaokrąglania zmiennoprzecinkowego ustawionym przez fesetround
. Wcześniej zaokrąglanie zawsze wybierało FE_TONEAREST
zachowanie. Ta zmiana dotyczy tylko programów utworzonych przy użyciu programu Visual Studio 2019 w wersji 16.2 lub nowszej. Aby użyć starszego zachowania zaokrąglania zmiennoprzecinkowego, połącz się z elementem "legacy_stdio_float_rounding.obj".
_snwprintf_s
jest wersją _snprintf_s
wieloznakową ; argumenty wskaźnika do _snwprintf_s
są ciągami o szerokim znaku. Wykrywanie błędów kodowania w _snwprintf_s
pliku może się różnić od tego w pliku _snprintf_s
. _snwprintf_s
, na przykład swprintf_s
, zapisuje dane wyjściowe w ciągu, a nie do miejsca docelowego typu FILE
.
Wersje tych funkcji z sufiksem _l
są identyczne, z tą różnicą, że używają parametru ustawień regionalnych przekazanych zamiast bieżących ustawień regionalnych wątku.
W języku C++używanie tych funkcji jest uproszczone przez przeciążenia szablonu; przeciążenia mogą automatycznie wnioskować długość buforu (eliminując konieczność określenia argumentu rozmiaru) i mogą automatycznie zastępować starsze, niezabezpieczone funkcje nowszymi, bezpiecznymi odpowiednikami. Aby uzyskać więcej informacji, zobacz Bezpieczne przeciążenia szablonów.
Mapowania procedur tekstu ogólnego
Tchar.h rutyna |
_UNICODE i _MBCS niezdefiniowane |
_MBCS zdefiniowany |
_UNICODE zdefiniowany |
---|---|---|---|
_sntprintf_s |
_snprintf_s |
_snprintf_s |
_snwprintf_s |
_sntprintf_s_l |
_snprintf_s_l |
_snprintf_s_l |
_snwprintf_s_l |
Wymagania
Procedura | Wymagany nagłówek |
---|---|
_snprintf_s , _snprintf_s_l |
<stdio.h> |
_snwprintf_s , _snwprintf_s_l |
<stdio.h> lub <wchar.h> |
Aby uzyskać więcej informacji o zgodności, zobacz Zgodność.
Przykład
// 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: ''
Zobacz też
We/Wy strumienia
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
, funkcje