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 < count
len
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žitcount
nebo méně znaků vbuffer
.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 vformat
. Formát se skládá z obyčejných znaků a má stejný tvar a funkci jakoformat
argument proprintf
. 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 ofbuffer
. Pokud funkce vezmechar
vyrovnávací paměť, velikost je v bajtech. Pokud funkce vezmewchar_t
vyrovnávací paměť, velikost určuje počet 16bitových slov. - Nechte
len
velikost formátovaných dat. Pokud funkce vezmechar
vyrovnávací paměť, velikost je v bajtech. Pokud funkce vezmewchar_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 nawchar_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ů. | – | No |
Chyba kódování během formátování | Pokud se zastaví zpracování specifikátoru s řetězce nebo Z S specifikace formátu, NULL umístí se na začátek vyrovnávací paměti. |
-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 |
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í NULL a 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 za vyrovnávací pamětí. | 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_errlist
errno
_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 count
ná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 rutina |
_UNICODE a _MBCS není definován |
_MBCS definovaný |
_UNICODE definovaný |
---|---|---|---|
_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