Delen via


snprintf _snprintf, _snprintf_l, _snwprintf_snwprintf_l

Hiermee schrijft u opgemaakte gegevens naar een tekenreeks. Er zijn veiligere versies van deze functies beschikbaar; zie _snprintf_s, _snprintf_s_l, _snwprintf_s, . _snwprintf_s_l

Syntaxis

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

Parameterwaarden

buffer
Opslaglocatie voor de uitvoer.

count
Maximum aantal tekens dat moet worden geschreven. Voor de functies die nodig zijn wchar_t, is dit het maximum aantal tekens dat moet worden geschreven.

format
Tekenreeks voor besturingselement opmaken.

argument
Optionele argumenten.

locale
De landinstelling die moet worden gebruikt om de uitvoer op te maken.

Zie de syntaxis van de indelingsspecificatie: printf en wprintf functies voor meer informatie.

Retourwaarde

Het aantal tekens dat naar de buffer zou zijn geschreven als count deze wordt genegeerd. Het aantal bevat niet het afsluitteken NULL .

Laten we len de lengte zijn van de opgemaakte gegevensreeks, niet inclusief het beëindigen NULL.
Als voor alle functies len < counttekens len worden opgeslagen in buffer, wordt een null-afsluiter toegevoegd en wordt het aantal tekens dat is geschreven, niet inclusief het eindteken NULL, geretourneerd.

De brede tekenversies van deze functies retourneren het aantal geschreven tekens, niet inclusief het eindteken NULL.

Zie het gedragsoverzicht voor meer informatie.

Opmerkingen

Vanaf het UCRT in Visual Studio 2015 en Windows 10 zijn snprintf ze niet meer identiek aan _snprintf. Het snprintf gedrag is nu C99-standaardconformant. Het verschil is dat als u onvoldoende buffer hebt, snprintf null het einde van de buffer beëindigt en het aantal tekens retourneert dat vereist is, terwijl _snprintf de buffer niet null-beëindigt en -1 retourneert. _snprintf() Bevat ook nog een teken in de uitvoer omdat de buffer niet null-beëindigt.

  • snprintf en de _snprintf functiesindeling en het opslaan count van of minder tekens in buffer.
  • snprintf slaat altijd een afsluitteken NULL op, waarbij de uitvoer zo nodig wordt afgekapt.
  • Als snprintf een waarde >count - 1 wordt geretourneerd, is de uitvoer afgekapt.
  • De _snprintf reeks functies voegt alleen een afsluitteken NULL toe als de opgemaakte tekenreekslengte strikt kleiner is dan count tekens.
  • Elke argument (indien aanwezig) wordt geconverteerd en is uitvoer volgens de bijbehorende indelingsspecificatie in format. De notatie bestaat uit gewone tekens en heeft dezelfde vorm en functie als het argument format voor printf. Als kopiëren plaatsvindt tussen tekenreeksen die overlappen, is het gedrag niet gedefinieerd.

Gedragsoverzicht

Voor de volgende tabel:

  • Laten we sizeOfBuffer de grootte van buffer. Als de functie een char buffer gebruikt, is de grootte in bytes. Als de functie een wchar_t buffer gebruikt, geeft de grootte het aantal 16-bits woorden op.
  • Laat len de grootte van de opgemaakte gegevens zijn. Als de functie een char buffer gebruikt, is de grootte in bytes. Als de functie een wchar_t buffer gebruikt, geeft de grootte het aantal 16-bits woorden op.
  • Tekens verwijzen naar char tekens voor functies die een char buffer nemen en tekens wchar_t voor functies die een wchar_t buffer innemen.
  • Zie Parametervalidatie voor meer informatie over de ongeldige parameterhandler.
Conditie Gedrag Retourwaarde errno Roept een ongeldige parameterhandler aan
Geslaagd Schrijft de tekens naar de buffer met behulp van de opgegeven notatietekenreeks. Het aantal geschreven tekens. Niet van toepassing. Nee.
Coderingsfout tijdens opmaak Als de verwerking van tekenreeksaanduidingen s, Sof Zindelingsspecificaties stopt, wordt een NULL aan het begin van de buffer geplaatst. -1 EILSEQ (42) Nee.
Coderingsfout tijdens opmaak Als de tekenaanduiding c wordt verwerkt of Cals het ongeldige teken wordt overgeslagen. Het aantal geschreven tekens wordt niet verhoogd voor het overgeslagen teken en er zijn ook geen gegevens voor geschreven. Het verwerken van de indelingsspecificatie wordt voortgezet na het overslaan van de aanduiding met de coderingsfout. Het aantal geschreven tekens, niet inclusief het eindteken NULL. EILSEQ (42) Nee.
buffer == NULL en count != 0 Als de uitvoering wordt voortgezet nadat de ongeldige parameterhandler is uitgevoerd, wordt een negatieve waarde ingesteld errno en geretourneerd. -1 EINVAL (22) Ja
count == 0 Het aantal tekens dat zou zijn geschreven, niet inclusief het eindteken NULL. U kunt dit resultaat gebruiken om voldoende bufferruimte toe te wijzen aan de tekenreeks en een afsluitfunctie NULLen vervolgens de functie opnieuw aan te roepen om de buffer te vullen. Niet van toepassing. Nee.
count < 0 Onveilig: de waarde wordt behandeld als niet-ondertekend, waardoor waarschijnlijk een grote waarde ontstaat die resulteert in het overschrijven van het geheugen dat volgt op de buffer. Het aantal geschreven tekens Niet van toepassing. Nee.
count < sizeOfBuffer en len <= count Alle gegevens worden geschreven en er wordt een afsluitteken NULL toegevoegd. Het aantal geschreven tekens, niet inclusief het eindteken NULL. Niet van toepassing. Nee.
count < sizeOfBuffer en len > count De eerste count-1 tekens worden geschreven gevolgd door een null-terminator. Het aantal tekens dat zou zijn geschreven, zou count overeenkomen met het aantal tekens dat moet worden uitgevoerd, met inbegrip van de null-terminator. Niet van toepassing. Nee.
count >= sizeOfBuffer en len < sizeOfBuffer Alle gegevens worden geschreven met een afsluit NULL. Het aantal geschreven tekens, niet inclusief het eindteken NULL. Niet van toepassing. Nee.
count >= sizeOfBuffer en len >= sizeOfBuffer Onveilig: overschrijft het geheugen dat de buffer volgt. Het aantal geschreven tekens, niet inclusief het eindteken NULL. Niet van toepassing. Nee.
format == NULL Er worden geen gegevens geschreven. Als de uitvoering wordt voortgezet nadat de ongeldige parameterhandler is uitgevoerd, wordt een negatieve waarde ingesteld errno en geretourneerd. -1 EINVAL (22) Ja

Zie , _doserrno, en errno_sys_errlistvoor meer informatie over deze en andere foutcodes_sys_nerr .

Belangrijk

Zorg ervoor dat dit format geen door de gebruiker gedefinieerde tekenreeks is. Omdat de _snprintf functies geen null-beëindiging garanderen, met name wanneer de retourwaarde is count, moet u ervoor zorgen dat ze worden gevolgd door code waarmee de null-afsluiter wordt toegevoegd. Zie Bufferoverschrijdingen voorkomen voor meer informatie.

Vanaf Windows 10 versie 2004 (build 19041) drukt de printf reeks functies exact vertegenwoordigbare zwevende kommanummers af volgens de IEEE 754-regels voor afronding. In eerdere versies van Windows zouden de zwevende kommanummers die eindigen op '5' altijd naar boven afronden. IEEE 754 geeft aan dat ze moeten afronden op het dichtstbijzijnde even cijfer (ook wel bekend als 'Afronding van bankier'). Beide moeten bijvoorbeeld printf("%1.0f", 1.5)printf("%1.0f", 2.5) worden afgerond op 2. Voorheen zou 1,5 afronden op 2 en 2,5 naar 3. Deze wijziging is alleen van invloed op exact vertegenwoordigbare getallen. Bijvoorbeeld: 2.35 (die, wanneer deze wordt weergegeven in het geheugen, dichter bij 2.350000000000008) blijft afronden tot 2,4. Afronding die door deze functies wordt uitgevoerd, respecteert nu ook de drijvende-komma-afrondingsmodus die is ingesteld door fesetround. Eerder koos afronding altijd voor FE_TONEAREST gedrag. Deze wijziging is alleen van invloed op programma's die zijn gebouwd met Visual Studio 2019 versie 16.2 en hoger. Als u het verouderde drijvendekomma-afrondingsgedrag wilt gebruiken, moet u een koppeling maken met legacy_stdio_float_rounding.obj.

_snwprintf is een brede versie van _snprintf; de aanwijzerargumenten die _snwprintf tekenreeksen breed zijn. Detectie van coderingsfouten in _snwprintf kan afwijken van de detectie in _snprintf. _snwprintf, net zoals swprintf, schrijft uitvoer naar een tekenreeks in plaats van een bestemming van het type FILE.

De versies van deze functies met het _l achtervoegsel zijn identiek, behalve dat ze de landinstellingparameter gebruiken die is doorgegeven in plaats van de huidige landinstelling voor threads.

In C++hebben deze functies overbelasting van sjablonen die de nieuwere, veiligere tegenhangers aanroepen. Zie Overbelasting van beveiligde sjablonen voor meer informatie.

Algemene routinetoewijzingen voor tekst

Tchar.h routine _UNICODE en _MBCS niet gedefinieerd _MBCS Gedefinieerd _UNICODE Gedefinieerd
_sntprintf _snprintf _snprintf _snwprintf
_sntprintf_l _snprintf_l _snprintf_l _snwprintf_l

Behoeften

Routine Vereiste header
snprintf, , _snprintf_snprintf_l <stdio.h>
_snwprintf, _snwprintf_l <stdio.h> of <wchar.h>

Zie Compatibiliteit voor meer compatibiliteitsinformatie.

Voorbeeld

// 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

Zie ook

Stream I/O-
sprintf _sprintf_l, swprintf, _swprintf_l__swprintf_l
fprintf, , , _fprintf_lfwprintf_fwprintf_l
printf, , , _printf_lwprintf_wprintf_l
scanf, , , _scanf_lwscanf_wscanf_l
sscanf, , , _sscanf_lswscanf_swscanf_l
vprintf functies