Sdílet prostřednictvím


snprintf, _snprintf, _snprintf_l, _snwprintf, _snwprintf_l

Zapisuje formátovaná data do řetězce. K dispozici jsou bezpečnější verze těchto funkcí; viz _snprintf_s, _snprintf_s_l, _snwprintf_s, _snwprintf_s_l.

Syntaxe

int snprintf(
   char *buffer,
   size_t count,
   const char *format [,
   argument] ...
);

int _snprintf(
   char *buffer,
   size_t count,
   const char *format [,
   argument] ...
);

int _snprintf_l(
   char *buffer,
   size_t count,
   const char *format,
   _locale_t locale [,
   argument] ...
);

int _snwprintf(
   wchar_t *buffer,
   size_t count,
   const wchar_t *format [,
   argument] ...
);

int _snwprintf_l(
   wchar_t *buffer,
   size_t count,
   const wchar_t *format,
   _locale_t locale [,
   argument] ...
);

template <size_t size>
int _snprintf(
   char (&buffer)[size],
   size_t count,
   const char *format [,
   argument] ...
); // C++ only

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

template <size_t size>
int _snwprintf(
   wchar_t (&buffer)[size],
   size_t count,
   const wchar_t *format [,
   argument] ...
); // C++ only

template <size_t size>
int _snwprintf_l(
   wchar_t (&buffer)[size],
   size_t count,
   const wchar_t *format,
   _locale_t locale [,
   argument] ...
); // 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é přebírají wchar_t, je maximální počet širokých znaků, které se mají napsat.

format
Řetězec řízení formátu

argument
Volitelné argumenty

locale
Národní prostředí, které se má použít k formátování výstupu.

Další informace naleznete v tématu Syntaxe specifikace formátu: printf a wprintf funkce.

Vrácená hodnota

Počet znaků, které by byly zapsány do vyrovnávací paměti, pokud count by byly ignorovány. Počet neobsahuje ukončovací NULL znak.

Nechte len délku formátovaného datového řetězce, nikoli ukončení NULL.
Pro všechny funkce, pokud len < countlen jsou znaky uloženy v buffer, je připojena ukončovací funkce null a počet znaků zapsaných, nikoli včetně ukončování NULL, je vrácen.

Široké verze znaků těchto funkcí vrací počet zapsaných širokých znaků, ne včetně ukončování NULL.

Podrobnosti najdete v souhrnu chování.

Poznámky

Počínaje UCRT v sadě Visual Studio 2015 a Windows 10 snprintf už není identický s _snprintf. Chování snprintf je nyní standardem C99. Rozdíl je v tom, že pokud dojdete z vyrovnávací paměti, snprintf ukončí konec vyrovnávací paměti null a vrátí počet znaků, které by byly požadovány, zatímco _snprintf neukončí vyrovnávací paměť null a vrátí hodnotu -1. Zahrnuje také jeden další znak ve výstupu, snprintf() protože neukončí vyrovnávací paměť null.

  • snprintf_snprintf a rodina funkcí formát a uložit count nebo méně znaků v buffer.
  • snprintf vždy uloží ukončovací NULL znak a v případě potřeby zkrátí výstup.
  • Pokud snprintf vrátí hodnotu >count - 1, výstup byl zkrácen.
  • Řada _snprintf funkcí připojí pouze ukončovací NULL znak, pokud je délka formátovaného řetězce přísně menší než count znaky.
  • Každý argument (pokud existuje) je převeden a je výstup podle odpovídající specifikace formátu v format. Formát se skládá z obyčejných znaků a má stejný tvar a funkci jako format argument pro printf. Pokud ke kopírování dojde mezi řetězci, které se překrývají, chování není definováno.

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ů. Číslo
Chyba kódování během formátování Pokud se zastaví zpracování specifikátoru sřetězce nebo ZSspecifikace formátu, NULL umístí se na začátek vyrovnávací paměti. -1 EILSEQ (42) Číslo
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) Číslo
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 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ěť. Číslo
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ů Číslo
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. Číslo
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. Číslo
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. Číslo
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. Číslo
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

Důležité

Ujistěte se, že format není uživatelem definovaný řetězec. _snprintf Vzhledem k tomu, že funkce nezaručují ukončení null , zejména pokud je countnávratová hodnota , ujistěte se, že jsou následované kódem, který přidává ukončovací znak null. 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.

_snwprintf je verze širokého znaku _snprintf; argumenty ukazatele na _snwprintf jsou řetězce širokých znaků. Detekce chyb kódování se _snwprintf může lišit od detekce v _snprintf. _snwprintf, stejně jako swprintf, zapisuje výstup do řetězce místo cíle typu FILE.

Verze těchto funkcí, které mají příponu _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ší, bezpečnější protějšky. Další informace naleznete v tématu Přetížení šablon zabezpečení.

Mapování rutin obecného textu

Tchar.h Rutinní _UNICODE a _MBCS není definován _MBCS Definovány _UNICODE Definovány
_sntprintf _snprintf _snprintf _snwprintf
_sntprintf_l _snprintf_l _snprintf_l _snwprintf_l

Požadavky

Rutina Požadovaný hlavičkový soubor
snprintf, _snprintf, _snprintf_l <stdio.h>
_snwprintf, _snwprintf_l <stdio.h> nebo <wchar.h>

Další informace o kompatibilitě najdete v tématu Kompatibilita.

Příklad

// crt_snprintf.c
// compile with: /W3
#include <stdio.h>
#include <stdlib.h>

#if !defined(__cplusplus)
typedef int bool;
const bool true = 1;
const bool false = 0;
#endif

#define FAIL 0 // change to 1 and see what happens

int main(void)
{
   char buffer[200];
   const static char s[] = "computer"
#if FAIL
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
#endif
   ;
   const char c = 'l';
   const int i = 35;
#if FAIL
   const double fp = 1e300; // doesn't fit in the buffer
#else
   const double fp = 1.7320534;
#endif
   /* !subtract one to prevent "squeezing out" the terminal null! */
   const int bufferSize = sizeof(buffer)/sizeof(buffer[0]) - 1;
   int bufferUsed = 0;
   int bufferLeft = bufferSize - bufferUsed;
   bool bSuccess = true;
   buffer[0] = 0;

   /* Format and print various data: */

   if (bufferLeft > 0)
   {
      int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
      bufferLeft, "   String: %s\n", s ); // C4996
      // Note: _snprintf is deprecated; consider _snprintf_s instead
      if (bSuccess = (perElementBufferUsed >= 0))
      {
         bufferUsed += perElementBufferUsed;
         bufferLeft -= perElementBufferUsed;
         if (bufferLeft > 0)
         {
            int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
            bufferLeft, "   Character: %c\n", c ); // C4996
            if (bSuccess = (perElementBufferUsed >= 0))
            {
               bufferUsed += perElementBufferUsed;
               bufferLeft -= perElementBufferUsed;
               if (bufferLeft > 0)
               {
                  int perElementBufferUsed = _snprintf(&buffer
                  [bufferUsed], bufferLeft, "   Integer: %d\n", i ); // C4996
                  if (bSuccess = (perElementBufferUsed >= 0))
                  {
                     bufferUsed += perElementBufferUsed;
                     bufferLeft -= perElementBufferUsed;
                     if (bufferLeft > 0)
                     {
                        int perElementBufferUsed = _snprintf(&buffer
                        [bufferUsed], bufferLeft, "   Real: %f\n", fp ); // C4996
                        if (bSuccess = (perElementBufferUsed >= 0))
                        {
                           bufferUsed += perElementBufferUsed;
                        }
                     }
                  }
               }
            }
         }
      }
   }

   if (!bSuccess)
   {
      printf("%s\n", "failure");
   }
   else
   {
      /* !store null because _snprintf doesn't necessarily (if the string
       * fits without the terminal null, but not with it)!
       * bufferUsed might be as large as bufferSize, which normally is
       * like going one element beyond a buffer, but in this case
       * subtracted one from bufferSize, so we're ok.
       */
      buffer[bufferUsed] = 0;
      printf( "Output:\n%s\ncharacter count = %d\n", buffer, bufferUsed );
   }
   return EXIT_SUCCESS;
}
Output:
   String: computer
   Character: l
   Integer: 35
   Real: 1.732053

character count = 69

Viz také

Vstupně-výstupní operace streamu
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 – funkce