Udostępnij za pośrednictwem


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_twartość , 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 < countlen znaki są przechowywane w bufferpliku , 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 przechowuje count lub mniej znaków w .buffer
  • snprintf zawsze przechowuje znak zakończenia NULL , 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ńczenia NULL 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 pliku format. Format składa się ze zwykłych znaków i ma taką samą formę i funkcję jak format argument dla printfelementu . 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 przyjmuje char bufor, rozmiar jest w bajtach. Jeśli funkcja przyjmuje wchar_t bufor, rozmiar określa liczbę 16-bitowych wyrazów.
  • Pozwól len na rozmiar sformatowanych danych. Jeśli funkcja przyjmuje char bufor, rozmiar jest w bajtach. Jeśli funkcja przyjmuje wchar_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 do wchar_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 sciągu , Slub 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_errlisti _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ą _snprintfwieloznakową ; 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