Sdílet prostřednictvím


vsnprintf, _vsnprintf, _vsnprintf_l, , _vsnwprintf_vsnwprintf_l

Formátovaný výstup zapište pomocí ukazatele na seznam argumentů. K dispozici jsou bezpečnější verze těchto funkcí; viz vsnprintf_s, _vsnprintf_s, _vsnprintf_s_l, _vsnwprintf_s, _vsnwprintf_s_l.

Syntaxe

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

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

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

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

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

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

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

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

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

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

Parametry

buffer
Umístění úložiště pro výstup.

count
Maximální počet znaků k zápisu U funkcí, které berou wchar_t, je to počet širokých znaků, které se mají zapsat.

format
Specifikace formátu.

argptr
Ukazatel na seznam argumentů.

locale
Národní prostředí, které se má použít.

Další informace naleznete v tématu Syntaxe specifikace formátu.

Návratová hodnota

Počet zapsaných znaků, bez započtení ukončující NULL, nebo záporné hodnoty, pokud dojde k chybě výstupu.

Podrobnosti najdete v souhrnu chování.

Poznámky

Každá z těchto funkcí převezme ukazatel na seznam argumentů, poté data zformátuje a zapíše do paměti až do count znaků, na které ukazuje buffer. Funkce vsnprintf vždy zapíše ukončovací znak s hodnotou null, i když zkrátí výstup. Když použijete _vsnprintf a _vsnwprintf, vyrovnávací paměť je ukončena hodnotou null pouze v případě, že je na jejím konci místo (to znamená, že počet znaků k zápisu je menší než count).

Počínaje UCRT v sadě Visual Studio 2015 a Windows 10 vsnprintf už není identický s _vsnprintf. Funkce vsnprintf odpovídá standardu C99; _vsnprintf je zachována kvůli zpětné kompatibilitě se starším kódem. Rozdíl je v tom, že pokud vyčerpáte vyrovnávací paměť, vsnprintf hodnota null ukončí konec vyrovnávací paměti a vrátí počet znaků, který by byl požadován, zatímco _vsnprintf vyrovnávací paměť neukončí hodnotou null a vrátí hodnotu -1. Zahrnuje také jeden další znak ve výstupu, _vsnprintf() protože neukončí vyrovnávací paměť null.

Důležité

Chcete-li předejít určitým druhům bezpečnostních rizik, ujistěte se, že format se nejedná o řetězec definovaný uživatelem. Další informace najdete v tématu Zabránění přetečení vyrovnávací paměti. Počínaje Windows 10 verze 2004 (build 19041) printf vytiskne řada funkcí přesně reprezentovatelná čísla s plovoucí desetinnou čárkou podle pravidel IEEE 754 pro zaokrouhlování. V předchozích verzích Windows by se vždy zaokrouhlila přesně reprezentovatelná čísla s plovoucí desetinnou čárkou končící na 5. IEEE 754 uvádí, že musí zaokrouhlit na nejbližší sudou číslici (označované také jako "Zaokrouhlování bankera"). Například obě printf("%1.0f", 1.5) a printf("%1.0f", 2.5) měly by se zaokrouhlit na 2. Dříve by se 1,5 zaokrouhlo na 2 a 2,5 by se zaokrouhlilo na 3. Tato změna má vliv jenom na přesně reprezentovatelná čísla. Například hodnota 2,35 (která je při znázornění v paměti blíže 2,350000000000008) pokračuje zaokrouhlit nahoru na 2,4. Zaokrouhlování provedené těmito funkcemi nyní respektuje také režim zaokrouhlování s plovoucí desetinou čárkou nastavený .fesetround Dříve bylo zaokrouhlení vždy zvoleno FE_TONEAREST chování. Tato změna má vliv jenom na programy vytvořené pomocí sady Visual Studio 2019 verze 16.2 a novější. Chcete-li použít starší chování zaokrouhlování s plovoucí desetinou čárkou, propojte s legacy_stdio_float_rounding.obj.

Poznámka:

Chcete-li zajistit, aby při volání _vsnprintf_vsnprintf_l_vsnwprintf , , a _vsnwprintf_l, bylo zajištěno, že count je striktně menší než délka vyrovnávací paměti a před voláním funkce inicializujte vyrovnávací paměť na hodnotu null.

Vzhledem k tomu, že vsnprintf vždy zapisuje ukončující hodnotu null, count parametr se může rovnat velikosti vyrovnávací paměti.

Verze těchto funkcí s příponou _l jsou identické s tím rozdílem, že používají předaný parametr locale namísto aktuálního národního prostředí vlákna.

V jazyce C++ mají tyto funkce přetížení šablony, která vyvolávají novější a bezpečné protějšky těchto funkcí. Další informace naleznete v tématu Přetížení šablon zabezpečení.

Souhrn chování

Pro následující tabulku:

  • Let sizeOfBuffer be the size of buffer. Pokud funkce vezme char vyrovnávací paměť, velikost je v bajtech. Pokud funkce vezme wchar_t vyrovnávací paměť, velikost určuje počet 16bitových slov.
  • Nechte len velikost formátovaných dat. Pokud funkce vezme char vyrovnávací paměť, velikost je v bajtech. Pokud funkce vezme wchar_t vyrovnávací paměť, velikost určuje počet 16bitových slov.
  • Znaky odkazují na char znaky pro funkce, které přebírají char vyrovnávací paměť, a na wchar_t znaky pro funkce, které přebírají wchar_t vyrovnávací paměť.
  • Další informace o neplatné obslužné rutině parametru naleznete v tématu Ověření parametru.
Podmínka Chování Návratová hodnota errno Vyvolá neplatnou obslužnou rutinu parametru.
Úspěch Zapíše znaky do vyrovnávací paměti pomocí zadaného řetězce formátu. Počet zapsaných znaků, nepočítaje ukončující znak null. není k dispozici Ne
Chyba kódování během formátování Pokud zpracováváte specifikátor sřetězce , S, nebo Z, zpracování specifikace formátu se zastaví. -1 EILSEQ (42) Ne
Chyba kódování během formátování Pokud specifikátor c znaku zpracování nebo C, je neplatný znak vynechán. Počet zapsaných znaků se pro přeskočený znak nezvýšuje, ani se pro něj nezapisují žádná data. Zpracování specifikace formátu pokračuje po vynechání specifikátoru s chybou kódování. Počet zapsaných znaků, včetně ukončení NULL. EILSEQ (42) Ne
buffer == NULL a count != 0 Pokud provádění pokračuje po spuštění neplatné obslužné rutiny parametru, nastaví errno a vrátí zápornou hodnotu. -1 EINVAL (22) Ano
buffer == NULL a count == 0 Nezapisují se žádná data Početznakůch NULL Tento výsledek můžete použít k přidělení dostatečného prostoru vyrovnávací paměti pro řetězec a ukončení NULLa následné volání funkce znovu vyplnit vyrovnávací paměť. není k dispozici Ne
count == 0 Nezapisují se žádná data -1 ERANGE (34) Ne
count < 0 Nebezpečné: Hodnota je považována za nepodepsanou, což pravděpodobně vytvoří velkou hodnotu, která vede k přepsání paměti, která následuje za vyrovnávací pamětí. Počet zapsaných znaků. není k dispozici Ne
count < sizeOfBuffer a len <= count Všechna data se zapíšou a připojí se ukončení NULL . Počet zapsaných znaků, včetně ukončení NULL. není k dispozici Ne
count < sizeOfBuffer a len > count Za prvními count-1 znaky následuje ukončovací znak null. Počet znaků, které by byly zapsány, odpovídaly count počtu znaků k výstupu, a ne zahrnutí ukončovací funkce null. není k dispozici Ne
count >= sizeOfBuffer a len < sizeOfBuffer Všechna data jsou zapsána s ukončením NULL. Počet zapsaných znaků, včetně ukončení NULL. není k dispozici Ne
count >= sizeOfBuffer a len >= sizeOfBuffer Nebezpečné: Přepíše paměť, která následuje za vyrovnávací pamětí. Počet zapsaných znaků, včetně ukončení NULL. není k dispozici Ne
format == NULL Nezapisuje se žádná data. Pokud provádění pokračuje po spuštění neplatné obslužné rutiny parametru, nastaví errno a vrátí zápornou hodnotu. -1 EINVAL (22) Ano

Informace o těchto a dalších kódech chyb naleznete v tématu _doserrnoerrno . _sys_errlist_sys_nerr

Mapování rutin obecného textu

TCHAR.H rutina _UNICODE a _MBCS není definován _MBCS definovaný _UNICODE definovaný
_vsntprintf _vsnprintf _vsnprintf _vsnwprintf
_vsntprintf_l _vsnprintf_l _vsnprintf_l _vsnwprintf_l

Požadavky

Rutina Požadovaná hlavička (C) Požadovaná hlavička (C++)
vsnprintf, , _vsnprintf_vsnprintf_l <stdio.h> <stdio.h> nebo <cstdio>
_vsnwprintf, _vsnwprintf_l <stdio.h> nebo <wchar.h> <stdio.h>, <wchar.h>, <cstdio>nebo <cwchar>

Funkce _vsnprintf, _vsnprintf_l, _vsnwprintf a _vsnwprintf_l jsou specifické pro společnost Microsoft. Další informace o kompatibilitě najdete v tématu Kompatibilita.

Příklad: Použití širokých znaků s _vsnwprintf()

// crt_vsnwprintf.c
// compile by using: cl /W3 crt_vsnwprintf.c

// To turn off error C4996, define this symbol:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <wtypes.h>

#define BUFFCOUNT (10)

void FormatOutput(LPCWSTR formatstring, ...)
{
    int nSize = 0;
    wchar_t buff[BUFFCOUNT];
    memset(buff, 0, sizeof(buff));
    va_list args;
    va_start(args, formatstring);
    // Note: _vsnwprintf is deprecated; consider vsnwprintf_s instead
    nSize = _vsnwprintf(buff, BUFFCOUNT - 1, formatstring, args); // C4996
    wprintf(L"nSize: %d, buff: %ls\n", nSize, buff);
    va_end(args);
}

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

Chování se změní, pokud místo toho použijete vsnprintf spolu s parametry úzkého řetězce. Parametrem count může být celá velikost vyrovnávací paměti a návratová hodnota je počet znaků, které by byly zapsány, pokud count by byla dostatečně velká:

Příklad: Použití vsnprintf() s úzkými řetězci

// crt_vsnprintf.c
// compile by using: cl /W4 crt_vsnprintf.c
#include <stdio.h>
#include <stdarg.h> // for va_list, va_start
#include <string.h> // for memset

#define BUFFCOUNT (10)

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

int main() {
    FormatOutput("%s %s", "Hi", "there");   //  8 chars + null
    FormatOutput("%s %s", "Hi", "there!");  //  9 chars + null
    FormatOutput("%s %s", "Hi", "there!!"); // 10 chars + null
}
nSize: 8, buff: Hi there
nSize: 9, buff: Hi there!
nSize: 10, buff: Hi there!

Viz také

Vstupně-výstupní operace streamu
vprintf funkce
Syntaxe specifikace formátu: printf a wprintf funkce
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