Sdílet prostřednictvím


vsnprintf, _vsnprintf, _vsnprintf_l, , _vsnwprintf_vsnwprintf_l

Zapíše formátovaný výstup 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 Pro funkce, které berou wchar_t, je počet širokých znaků, které se mají napsat.

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.

Vrácená hodnota

Počet zapsaných znaků, které neobsahují ukončení NULLnebo zápornou hodnotu, pokud dojde k chybě výstupu.

Podrobnosti najdete v souhrnu chování.

Poznámky

Každá z těchto funkcí přebírá ukazatel na seznam argumentů, pak formátuje data a zapisuje do count paměti odkazované na buffer. Funkce vsnprintf vždy zapíše ukončovací znak null, i když zkrátí výstup. Při použití _vsnprintf a _vsnwprintf, vyrovnávací paměť je ukončena null-ukončena pouze v případě, že je na konci místnosti (to znamená, že pokud 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 udržována kvůli zpětné kompatibilitě se starším kódem. Rozdíl je v tom, že pokud dojdete do vyrovnávací paměti, vsnprintf ukončí konec vyrovnávací paměti null a vrátí počet znaků, které by byly požadovány, zatímco _vsnprintf neukončí vyrovnávací paměť null a vrátí -1. Zahrnuje také jeden další znak ve výstupu, _vsnprintf() protože neukončí vyrovnávací paměť null.

Důležité

Pokud chcete zabránit určitým druhům rizik zabezpečení, ujistěte se, že format se nejedná o uživatelem definovaný řetězec. 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ší. Pokud chcete použít starší chování zaokrouhlení s plovoucí desetinou čárkou, použijte odkaz na legacy_stdio_float_rounding.obj.

Poznámka:

Chcete-li zajistit, aby při volání _vsnprintf, _vsnprintf_l_vsnwprintf a , je k dispozici prostor pro ukončení null a _vsnwprintf_l, ujistěte se, že count je přísně menší než délka vyrovnávací paměti a inicializovat vyrovnávací paměť na hodnotu null před voláním funkce.

Protože vsnprintf vždy zapisuje ukončující hodnotu null, count může být parametr roven velikosti vyrovnávací paměti.

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

V jazyce C++ mají tyto funkce přetížení šablon, které vyvolávají novější zabezpečené 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í Vrácená hodnota errno Vyvolá neplatnou obslužnou rutinu parametru.
Success Zapíše znaky do vyrovnávací paměti pomocí zadaného řetězce formátu. Počet zapsaných znaků, nepočítá se ukončující znak null. No
Chyba kódování během formátování Pokud se zastaví zpracování specifikátoru sřetězce , Snebo Z, zpracování specifikace formátu. -1 EILSEQ (42) No
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) No
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
count == 0 Nezapisuje 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ěť. No
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ů. No
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. No
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. No
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. No
count >= sizeOfBuffer a len >= sizeOfBuffer Nebezpečné: přepíše paměť, která následuje po vyrovnávací paměti. Počet zapsaných znaků, včetně ukončení NULL. No
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 , , , a_sys_nerr . _sys_errlisterrno_doserrno

Mapování rutin obecného textu

TCHAR.H Rutinní _UNICODE a _MBCS není definován _MBCS Definovány _UNICODE Definovány
_vsntprintf _vsnprintf _vsnprintf _vsnwprintf
_vsntprintf_l _vsnprintf_l _vsnprintf_l _vsnwprintf_l

Požadavky

Rutina Povinná hlavička (C) Povinná 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 _vsnprintfa , _vsnwprintf_vsnprintf_l_vsnwprintf_l jsou specifické pro 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. Parametr 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 byly 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