Udostępnij za pośrednictwem


_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_twartość , 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 do wchar_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 sciągów , Slub 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 == NULLi i sizeOfBuffer == 0count == 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 >= sizeOfBufferi i len >= sizeOfBuffercount != _TRUNCATE Jeśli wykonanie będzie kontynuowane po wykonaniu nieprawidłowego programu obsługi parametrów, ustawia errno, ustawia buffer[0] == NULLwartoś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 NULLcią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_errlisti _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_swieloznakową ; 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