Udostępnij przez


vsnprintf_s, , _vsnprintf_s, _vsnprintf_s_l, , _vsnwprintf_s_vsnwprintf_s_l

Zapisz sformatowane dane wyjściowe przy użyciu wskaźnika do listy argumentów. Te funkcje są wersjami vsnprintf, _vsnprintf, , _vsnprintf_l, _vsnwprintfz _vsnwprintf_l ulepszeniami zabezpieczeń zgodnie z opisem w temacie Funkcje zabezpieczeń w CRT.

Składnia

int vsnprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format,
   va_list argptr
);

int _vsnprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format,
   va_list argptr
);

int _vsnprintf_s_l(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format,
   _locale_t locale,
   va_list argptr
);

int _vsnwprintf_s(
   wchar_t *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const wchar_t *format,
   va_list argptr
);

int _vsnwprintf_s_l(
   wchar_t *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const wchar_t *format,
   _locale_t locale,
   va_list argptr
);

template <size_t size>
int _vsnprintf_s(
   char (&buffer)[size],
   size_t count,
   const char *format,
   va_list argptr
); // C++ only

template <size_t size>
int _vsnwprintf_s(
   wchar_t (&buffer)[size],
   size_t count,
   const wchar_t *format,
   va_list argptr
); // C++ only

Parametry

buffer
Miejsce przechowywania danych wyjściowych.

sizeOfBuffer
Rozmiar danych wyjściowych buffer for. Rozmiar w bajtach dla funkcji, które przyjmują char, i słowa dla tych, które przyjmują wchar_t.

count
Maksymalna liczba znaków do zapisania bez zakończenia NULL. W przypadku funkcji, które przyjmują wchar_t, jest to liczba szerokich znaków do napisania. Lub _TRUNCATE.

format
Specyfikacja formatu.

argptr
Wskaźnik do listy argumentów.

locale
Ustawienia regionalne, które mają być używane podczas formatowania danych wyjściowych.

Aby uzyskać więcej informacji, zobacz Specyfikacje formatu.

Wartość zwracana

Liczba zapisanych znaków, nie wliczając kończącego NULLlub wartości ujemnej, jeśli wystąpi błąd wyjściowy.

Aby uzyskać szczegółowe informacje, zobacz Podsumowanie zachowania.

Uwagi

Każda z tych funkcji pobiera wskaźnik do listy argumentów, a następnie formatuje i zapisuje do count znaków podanych danych w pamięci wskazywanej przez buffer i dołącza kończący NULL.

W kompilacjach debugowania pozostałe sizeOfBuffer bajty po zakończeniu NULL są wypełniane przez "xFE", jak opisano w _CrtSetDebugFillThreshold.

Wersje tych funkcji z sufiksem _l są identyczne, z tą różnicą, że używają parametru locale przekazanego zamiast bieżących ustawień regionalnych wątku.

vsnprintf_s jest identyczny i _vsnprintf_s uwzględniony w celu zapewnienia zgodności ze standardem ANSI. _vnsprintf jest zachowywany w celu zapewnienia zgodności z poprzednimi wersjami.

Podsumowanie zachowania

W poniższej tabeli:

  • Pozwól len na 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.
Warunek 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 N/A Nie.
Błąd kodowania podczas formatowania Jeśli przetwarzanie specyfikatora sciągu , S, lub Z, przetwarzanie specyfikacji formatu zostanie zatrzymane. -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 == NULLoraz sizeOfBuffer == 0count == 0 Żadne dane nie są zapisywane. 0 N/A Nie.
buffer == NULL oraz 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. 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 != NULLoraz sizeOfBuffer != 0count == 0 Bufor zostaje NULL zakończony. -1 N/A Nie.
count == 0 Nie zapisuje żadnych danych i zwraca liczbę znaków, które zostałyby zapisane, nie wliczając kończącego NULL. Liczba znaków, które zostałyby zapisane bez zakończenia NULL. N/A 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. N/A Nie.
count < sizeOfBuffer i len <= count Wszystkie dane są zapisywane i dołączane są kończenie NULL . Liczba zapisanych znaków. N/A Nie.
count < sizeOfBuffer i len > count Pierwsze count znaki są pisane. -1 N/A Nie.
count >= sizeOfBuffer i len < sizeOfBuffer Wszystkie dane są zapisywane z kończeniem NULL. Liczba zapisanych znaków, a nie łącznie z kończeniem NULL. N/A Nie.
count >= sizeOfBufferoraz len >= sizeOfBuffercount != _TRUNCATE Jeśli wykonywanie jest kontynuowane po wykonaniu procedury obsługi nieprawidłowego parametru, ustawia errno, ustawia buffer[0] == NULLi zwraca wartość ujemną. -1 ERANGE (34) Tak
count == _TRUNCATE i len >= sizeOfBuffer Zapisuje tyle ciągu, ile mieści się w buffer, łącznie z zakończeniem NULL. -1 N/A Nie.
count == _TRUNCATE i len < sizeOfBuffer Zapisuje cały ciąg do buffer z zakończeniem NULL. Liczba zapisanych znaków. N/A 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. Aby uzyskać więcej informacji, zobacz Unikanie przekroków buforu. 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.

Uwaga / Notatka

Aby upewnić się, że jest miejsce na zakończenie NULL, upewnij się, że count jest ono ściśle mniejsze niż długość bufora, lub użyj _TRUNCATE.

W języku C++ korzystanie z tych funkcji jest uproszczone przez przeciążenia szablonów; Przeciążenia mogą automatycznie wnioskować o długości buforu (eliminując konieczność określania argumentu rozmiaru) i mogą automatycznie zastępować starsze, niezabezpieczone funkcje nowszymi, bezpiecznymi odpowiednikami. Aby uzyskać więcej informacji, zobacz Bezpieczne przeciążenia szablonów.

Wskazówka

Jeśli wystąpi niezdefiniowany błąd zewnętrzny _vsnprintf_s i używasz uniwersalnego środowiska uruchomieniowego języka C, dodaj legacy_stdio_definitions.lib do zestawu bibliotek do połączenia. Środowisko uruchomieniowe uniwersalnego języka C nie eksportuje tej funkcji bezpośrednio, a zamiast tego jest zdefiniowane w tekście w <stdio.h>programie . Aby uzyskać więcej informacji, zobacz Omówienie potencjalnych problemów z uaktualnianiem i zmianami zgodności programu Visual Studio 2015.

Mapowania procedur tekstu ogólnego

TCHAR.H rutyna _UNICODE i _MBCS niezdefiniowane _MBCS zdefiniowany _UNICODE zdefiniowany
_vsntprintf_s _vsnprintf_s _vsnprintf_s _vsnwprintf_s
_vsntprintf_s_l _vsnprintf_s_l _vsnprintf_s_l _vsnwprintf_s_l

Wymagania

Procedura Wymagany nagłówek Opcjonalne nagłówki
vsnprintf_s <stdio.h> i <stdarg.h> <varargs.h>*
_vsnprintf_s, _vsnprintf_s_l <stdio.h> i <stdarg.h> <varargs.h>*
_vsnwprintf_s, _vsnwprintf_s_l <stdio.h> lub <wchar.h>, oraz <stdarg.h> <varargs.h>*

* Wymagane do zapewnienia zgodności z systemem UNIX V.

Aby uzyskać więcej informacji o zgodności, zobacz Zgodność.

Przykład

// crt_vsnprintf_s.cpp
#include <stdio.h>
#include <wtypes.h>

void FormatOutput(LPCSTR formatstring, ...)
{
   int nSize = 0;
   char buff[10];
   memset(buff, 0, sizeof(buff));
   va_list args;
   va_start(args, formatstring);
   nSize = vsnprintf_s( buff, _countof(buff), _TRUNCATE, formatstring, args);
   printf("nSize: %d, buff: %s\n", nSize, buff);
   va_end(args);
}

int main() {
   FormatOutput("%s %s", "Hi", "there");
   FormatOutput("%s %s", "Hi", "there!");
   FormatOutput("%s %s", "Hi", "there!!");
}
nSize: 8, buff: Hi there
nSize: 9, buff: Hi there!
nSize: -1, buff: Hi there!

Zobacz także

We/Wy strumienia
vprintf funkcjonalności
fprintf, , _fprintf_l, , fwprintf_fwprintf_l
printf, , _printf_l, , wprintf_wprintf_l
sprintf, _sprintf_l, swprintf, , _swprintf_l__swprintf_l
va_arg, , va_copy, , va_endva_start