snprintf
, , _snprintf
, _snprintf_l
, , _snwprintf
_snwprintf_l
Zapisuje sformatowane dane do ciągu. Dostępne są bezpieczniejsze wersje tych funkcji; zobacz _snprintf_s
, , _snwprintf_s
_snprintf_s_l
, , _snwprintf_s_l
.
Składnia
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
Lokalizacja w pamięci dla danych wyjściowych.
count
Maksymalna liczba znaków do zapisu. W przypadku funkcji, które przyjmują wchar_t
wartość , jest to maksymalna liczba znaków do zapisania.
format
Ciąg kontroli formatu.
argument
Argumenty opcjonalne.
locale
Ustawienia regionalne do formatowania danych wyjściowych.
Aby uzyskać więcej informacji, zobacz Składnia specyfikacji formatu: printf
i wprintf
funkcje.
Wartość zwracana
Liczba znaków, które zostałyby zapisane w buforze, gdyby count
zostało zignorowane. Liczba nie zawiera znaku zakończenia NULL
.
Niech len
długość sformatowanego ciągu danych nie obejmuje zakończenia NULL
.
W przypadku wszystkich funkcji, jeśli len < count
len
znaki są przechowywane w buffer
pliku , dołączany jest terminator o wartości null, a liczba zapisanych znaków, a nie w tym terminowanie NULL
, jest zwracana.
Szerokie wersje znaków tych funkcji zwracają liczbę zapisanych znaków szerokich, a nie w tym zakończenie NULL
.
Aby uzyskać szczegółowe informacje, zobacz Podsumowanie zachowania.
Uwagi
Począwszy od UCRT w programach Visual Studio 2015 i Windows 10, snprintf
nie jest już identyczny z _snprintf
. Zachowanie snprintf
jest teraz zgodne ze standardem C99. Różnica polega na tym, że jeśli zabraknie buforu, wartość null kończy koniec buforu i zwraca liczbę znaków, snprintf
które byłyby wymagane, podczas gdy _snprintf
bufor nie kończy się wartością null i zwraca wartość -1. Ponadto zawiera jeszcze jeden znak w danych wyjściowych, snprintf()
ponieważ nie powoduje zakończenia buforu o wartości null.
snprintf
_snprintf
oraz rodzina funkcji formatuje i przechowujecount
lub mniej znaków w .buffer
snprintf
zawsze przechowuje znak zakończeniaNULL
, obcinając dane wyjściowe w razie potrzeby.- Jeśli
snprintf
zwraca wartość >count
— 1, dane wyjściowe zostały obcięte. - Rodzina
_snprintf
funkcji dołącza znak zakończeniaNULL
tylko wtedy, gdy sformatowana długość ciągu jest ściśle mniejsza niżcount
znaki. - Każda
argument
(jeśli istnieje) jest konwertowana i jest wynikiem wyjściowym zgodnie z odpowiednią specyfikacją formatu w plikuformat
. Format składa się ze zwykłych znaków i ma taką samą formę i funkcję jakformat
argument dlaprintf
elementu . Jeśli kopiowanie odbywa się między nakładającymi się ciągami, zachowanie jest niezdefiniowane.
Podsumowanie zachowania
W poniższej tabeli:
- Niech
sizeOfBuffer
będzie rozmiar .buffer
Jeśli funkcja przyjmujechar
bufor, rozmiar jest w bajtach. Jeśli funkcja przyjmujewchar_t
bufor, rozmiar określa liczbę 16-bitowych wyrazów. - Pozwól
len
na rozmiar sformatowanych danych. Jeśli funkcja przyjmujechar
bufor, rozmiar jest w bajtach. Jeśli funkcja przyjmujewchar_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 dowchar_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.
Stan | 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. | Nie dotyczy | Nie. |
Błąd kodowania podczas formatowania | Jeśli przetwarzanie specyfikatora s ciągu , S lub Z , przetwarzanie specyfikacji formatu zostanie zatrzymane, element NULL zostanie umieszczony na początku buforu. |
-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 == NULL i 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 |
count == 0 |
Liczba znaków, które zostałyby zapisane, a nie łącznie z kończeniem NULL . Możesz użyć tego wyniku, aby przydzielić wystarczającą ilość miejsca buforu dla ciągu i zakończenia NULL , a następnie wywołać funkcję ponownie, aby wypełnić bufor. |
Nie dotyczy | 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 | Nie dotyczy | Nie. |
count < sizeOfBuffer i len <= count |
Wszystkie dane są zapisywane i dołączane są kończenie NULL . |
Liczba zapisanych znaków, a nie łącznie z kończeniem NULL . |
Nie dotyczy | Nie. |
count < sizeOfBuffer i len > count |
count-1 Pierwsze znaki są zapisywane, a następnie terminator o wartości null. |
Liczba zapisanych znaków count była zgodna z liczbą znaków w danych wyjściowych, a nie w tym terminatorem o wartości null. |
Nie dotyczy | 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 . |
Nie dotyczy | Nie. |
count >= sizeOfBuffer i len >= sizeOfBuffer |
Niebezpieczne: zastępuje pamięć, która następuje po buforze. | Liczba zapisanych znaków, a nie łącznie z kończeniem NULL . |
Nie dotyczy | 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_errlist
i _sys_nerr
.
Ważne
Upewnij się, że format
nie jest to ciąg zdefiniowany przez użytkownika. _snprintf
Ponieważ funkcje nie gwarantują zakończenia wartości null — w szczególności gdy zwracana wartość to count
— upewnij się, że następuje po nich kod, który dodaje terminator o wartości null. 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
.
_snwprintf
jest wersją _snprintf
wieloznakową ; argumenty wskaźnika do _snwprintf
są ciągami o szerokim znaku. Wykrywanie błędów kodowania w _snwprintf
programie może różnić się od wykrywania w programie _snprintf
. _snwprintf
, podobnie jak swprintf
, zapisuje dane wyjściowe w ciągu zamiast miejsca docelowego typu FILE
.
Wersje tych funkcji, które mają _l
sufiks, są identyczne, z tą różnicą, że używają parametru ustawień regionalnych przekazanych zamiast bieżących ustawień regionalnych wątku.
W języku C++te funkcje mają przeciążenia szablonu, które wywołują nowsze, bezpieczniejsze odpowiedniki. Aby uzyskać więcej informacji, zobacz Bezpieczne przeciążenia szablonów.
Mapowania procedur tekstu ogólnego
Tchar.h rutyna |
_UNICODE i _MBCS niezdefiniowane |
_MBCS zdefiniowany |
_UNICODE zdefiniowany |
---|---|---|---|
_sntprintf |
_snprintf |
_snprintf |
_snwprintf |
_sntprintf_l |
_snprintf_l |
_snprintf_l |
_snwprintf_l |
Wymagania
Procedura | Wymagany nagłówek |
---|---|
snprintf , , _snprintf _snprintf_l |
<stdio.h> |
_snwprintf , _snwprintf_l |
<stdio.h> lub <wchar.h> |
Aby uzyskać więcej informacji o zgodności, zobacz Zgodność.
Przykład
// 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
Zobacz też
We/Wy strumienia
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
, funkcje