Partager via


snprintf, , _snprintf_snprintf_l, , _snwprintf_snwprintf_l

Écrit des données mises en forme dans une chaîne. Des versions plus sécurisées de ces fonctions sont disponibles ; voir , , _snwprintf_s_snprintf_s_l, _snwprintf_s_l._snprintf_s

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

Paramètres

buffer
Emplacement de stockage pour la sortie.

count
Nombre maximal de caractères à écrire. Pour les fonctions qui prennent wchar_t, il s’agit du nombre maximal de caractères larges à écrire.

format
Chaîne de contrôle de format.

argument
Arguments facultatifs.

locale
Paramètres régionaux à utiliser pour mettre en forme la sortie.

Pour plus d’informations, consultez la syntaxe de spécification de format : printf et wprintf les fonctions.

Valeur retournée

Nombre de caractères qui auraient été écrits dans la mémoire tampon s’ils count étaient ignorés. Le nombre n’inclut pas le caractère de NULL fin.

Supposons que la longueur de la chaîne de données mise en forme n’inclue len pas la fin NULL.
Pour toutes les fonctions, si len < count, les len caractères sont stockés dans buffer, un point de terminaison Null est ajouté et le nombre de caractères écrits, sans inclure la fin NULL, est retourné.

Les versions de caractères larges de ces fonctions retournent le nombre de caractères larges écrits, sans inclure la fin NULL.

Pour plus d’informations, consultez le résumé du comportement.

Notes

Depuis le composant UCRT dans Visual Studio 2015 et Windows 10, snprintf n’est plus identique à _snprintf. Le snprintf comportement est désormais conforme aux normes C99. La différence est que si vous n’avez plus de mémoire tampon, snprintf null met fin à la fin de la mémoire tampon et retourne le nombre de caractères qui auraient été requis, tandis que _snprintf ne termine pas la mémoire tampon et retourne -1. snprintf() Inclut également un caractère supplémentaire dans la sortie, car il n’arrête pas la mémoire tampon.

  • snprintf et la _snprintf famille de fonctions formatent et stockent count ou moins de caractères dans buffer.
  • snprintf stocke toujours un caractère de fin NULL , tronqué la sortie si nécessaire.
  • Si snprintf elle retourne une valeur >count - 1, la sortie a été tronquée.
  • La _snprintf famille de fonctions ajoute uniquement un caractère de NULL fin si la longueur de chaîne mise en forme est strictement inférieure à celle des count caractères.
  • Chaque argument (le cas échéant) est converti et sorti selon la spécification de format correspondante dans format. Le format se compose de caractères ordinaires et a la même forme et la même fonction que l’argument format pour printf. Si une copie se produit entre des chaînes qui se chevauchent, le comportement est indéfini.

Résumé du comportement

Pour le tableau suivant :

  • Supposons sizeOfBuffer que la taille soit la taille de buffer. Si la fonction prend une char mémoire tampon, la taille est en octets. Si la fonction prend une wchar_t mémoire tampon, la taille spécifie le nombre de mots 16 bits.
  • Supposons len que la taille des données mises en forme soit la taille. Si la fonction prend une char mémoire tampon, la taille est en octets. Si la fonction prend une wchar_t mémoire tampon, la taille spécifie le nombre de mots 16 bits.
  • Les caractères font référence aux char caractères des fonctions qui prennent une char mémoire tampon et aux wchar_t caractères des fonctions qui prennent une wchar_t mémoire tampon.
  • Pour plus d’informations sur le gestionnaire de paramètres non valide, consultez Validation des paramètres.
Condition Comportement Valeur retournée errno Appelle un gestionnaire de paramètres non valides
Réussite Écrit les caractères dans la mémoire tampon à l’aide de la chaîne de format spécifiée. Nombre de caractères écrits. S/O Non
Erreur d’encodage lors de la mise en forme Si le spécificateur sde chaîne de traitement , Sou , le Ztraitement des spécifications de format s’arrête, il NULL est placé au début de la mémoire tampon. -1 EILSEQ (42) Non
Erreur d’encodage lors de la mise en forme Si le spécificateur c de caractère de traitement ou C, le caractère non valide est ignoré. Le nombre de caractères écrits n’est pas incrémenté pour le caractère ignoré, ni aucune donnée n’est écrite pour elle. Le traitement de la spécification du format se poursuit après avoir ignoré le spécificateur avec l’erreur d’encodage. Nombre de caractères écrits, sans inclure la fin NULL. EILSEQ (42) Non
buffer == NULL et count != 0 Si l’exécution se poursuit après l’exécution du gestionnaire de paramètres non valide, définit errno et retourne une valeur négative. -1 EINVAL (22) Oui
count == 0 Nombre de caractères qui auraient été écrits, sans inclure la fin NULL. Vous pouvez utiliser ce résultat pour allouer suffisamment d’espace tampon pour la chaîne et une fin NULL, puis appeler à nouveau la fonction pour remplir la mémoire tampon. S/O Non
count < 0 Non sécurisé : la valeur est traitée comme non signée, ce qui crée probablement une valeur importante qui entraîne le remplacement de la mémoire qui suit la mémoire tampon. Nombre de caractères écrits S/O Non
count < sizeOfBuffer et len <= count Toutes les données sont écrites et une fin NULL est ajoutée. Nombre de caractères écrits, sans inclure la fin NULL. S/O Non
count < sizeOfBuffer et len > count Les premiers count-1 caractères sont écrits suivis d’un terminateur null. Le nombre de caractères qui auraient été écrits avait count mis en correspondance le nombre de caractères à générer, sans inclure le terminateur Null. S/O Non
count >= sizeOfBuffer et len < sizeOfBuffer Toutes les données sont écrites avec une fin NULL. Nombre de caractères écrits, sans inclure la fin NULL. S/O Non
count >= sizeOfBuffer et len >= sizeOfBuffer Non sécurisé : remplace la mémoire qui suit la mémoire tampon. Nombre de caractères écrits, sans inclure la fin NULL. S/O Non
format == NULL Aucune donnée n’est écrite. Si l’exécution se poursuit après l’exécution du gestionnaire de paramètres non valide, définit errno et retourne une valeur négative. -1 EINVAL (22) Oui

Pour plus d’informations sur ces codes d’erreur et d’autres codes d’erreur, consultez , , _sys_errlisterrnoet _sys_nerr._doserrno

Important

Assurez-vous que format n'est pas une chaîne définie par l'utilisateur. Étant donné que les _snprintf fonctions ne garantissent pas l’arrêt null, en particulier lorsque la valeur de retour est count, assurez-vous qu’elles sont suivies par le code qui ajoute le terminateur Null. Pour plus d’informations, consultez Solutions contre les dépassements de mémoire tampon.

À compter de Windows 10 version 2004 (build 19041), la famille de fonctions printf imprime exactement les nombres à virgule flottante pouvant être représentés en suivant les règles IEEE 754 pour l’arrondi. Dans les versions précédentes de Windows, les nombres à virgule flottante pouvant être représentés exactement qui se terminent par « 5 » sont toujours arrondis à la valeur supérieure. IEEE 754 indique qu’ils doivent être arrondis au chiffre pair le plus proche (également appelé « arrondi du banquier »). Par exemple, printf("%1.0f", 1.5) et printf("%1.0f", 2.5) doivent être arrondis à 2. Avant, 1.5 aurait été arrondi à 2 et 2.5 à 3. Ce changement affecte uniquement les nombres représentables avec précision. Par exemple, 2.35 (qui, lorsqu’il est représenté en mémoire, est plus proche de 2.35000000000000008) continue d’être arrondi à la valeur supérieure 2.4. L’arrondi effectué par ces fonctions respecte également le mode d’arrondi à virgule flottante défini par fesetround. Avant, l’arrondi choisissait toujours le comportement FE_TONEAREST. Ce changement affecte uniquement les programmes générés à l’aide de Visual Studio 2019 versions 16.2 et ultérieures. Pour utiliser le comportement d’arrondi à virgule flottante héritée, liez avec legacy_stdio_float_rounding.obj.

_snwprintf est une version à caractères larges de _snprintf; les arguments de pointeur de _snwprintf sont des chaînes à caractères larges. La détection des erreurs _snwprintf d’encodage peut différer de la détection dans _snprintf. _snwprintf, tout comme swprintf, écrit la sortie dans une chaîne au lieu d'une destination de type FILE.

Les versions de ces fonctions avec le suffixe _l sont identiques, sauf qu'elles utilisent les paramètres régionaux passés au lieu des paramètres régionaux du thread actuel.

En C++, ces fonctions ont des surcharges de modèle qui appellent les équivalents plus récents et plus sécurisés. Pour plus d'informations, consultez Sécuriser les surcharges de modèle.

Mappages de routines de texte générique

Routine Tchar.h _UNICODE et _MBCS non définis _MBCS défini _UNICODE défini
_sntprintf _snprintf _snprintf _snwprintf
_sntprintf_l _snprintf_l _snprintf_l _snwprintf_l

Spécifications

Routine En-tête requis
snprintf, , _snprintf_snprintf_l <stdio.h>
_snwprintf, _snwprintf_l <stdio.h> ou <wchar.h>

Pour plus d’informations sur la compatibilité, consultez Compatibility.

Exemple

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

Voir aussi

E/S de flux
sprintf, , _sprintf_lswprintf, , _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, fonctions