vsprintf

PRINTF(3)                  Manuel du programmeur Linux                 PRINTF(3)



NOM
       printf, fprintf, dprintf, sprintf, snprintf, vprintf, vfprintf, vdprintf,
       vsprintf, vsnprintf - Formatage des sorties

SYNOPSIS
       #include <stdio.h>

       int printf(const char *restrict format, ...);
       int fprintf(FILE *restrict stream,
                   const char *restrict format, ...);
       int dprintf(int fd,
                   const char *restrict format, ...);
       int sprintf(char *restrict str,
                   const char *restrict format, ...);
       int snprintf(char *restrict str, size_t size,
                   const char *restrict format, ...);

       #include <stdarg.h>

       int vprintf(const char *restrict format, va_list ap);
       int vfprintf(FILE *restrict stream,
                   const char *restrict format, va_list ap);
       int vdprintf(int fd,
                   const char *restrict format, va_list ap);
       int vsprintf(char *restrict str,
                   const char *restrict format, va_list ap);
       int vsnprintf(char *restrict str, size_t size,
                   const char *restrict format, va_list ap);

   Exigences de macros de test de fonctionnalités pour la glibc (consulter
   feature_test_macros(7)) :

       snprintf(), vsnprintf() :
           _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE
               || /* Glibc <= 2.19: */ _BSD_SOURCE

       dprintf(), vdprintf() :
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L
           Before glibc 2.10:
               _GNU_SOURCE

DESCRIPTION
       The functions in the printf()  family produce output according to a
       format as described below.  The functions printf()  and vprintf() write
       output to stdout, the standard output stream; fprintf()  and vfprintf()
       write output to the given output stream; sprintf(), snprintf(),
       vsprintf(), and vsnprintf()  write to the character string str.

       La fonction dprintf() est équivalente à fprintf() si ce n'est qu'elle
       écrit dans un descripteur de fichier fd plutôt que dans un flux stdio.

       Les fonctions snprintf() et vsnprintf() écrivent au plus taille octets
       (octet NULL final (« \0 ») compris) dans chaîne.

       Les fonctions vprintf(), vfprintf(), vdprintf(), vsprintf() et
       vsnprintf() sont équivalentes aux fonctions printf(), fprintf(),
       dprintf(), sprintf() et snprintf() respectivement, mais elles emploient
       un tableau va_list à la place d'un nombre variable d'arguments. Ces
       fonctions n'appellent pas la macro va_end. Du fait qu'elles appellent la
       macro va_arg, la valeur de ap n'est pas définie après l'appel. Consultez
       stdarg(3).

       Toutes ces fonctions écrivent leurs sorties sous le contrôle d'une chaîne
       de format qui indique les conversions à apporter aux arguments suivants
       (ou accessibles à travers les arguments de taille variable de stdarg(3)).

       C99 et POSIX.1-2001 spécifient que les résultats ne sont pas définis si
       un appel à sprintf(), snprintf(), vsprintf() ou vsnprintf() causait la
       copie entre des objets qui se chevauchent (par exemple, si le tableau de
       la chaîne cible et un des paramètres d'entrée se trouvent dans le même
       tampon). Consultez la section NOTES.

   CHAÎNE DE FORMAT
       Le format de conversion est indiqué par une chaîne de caractères,
       commençant et se terminant dans son état de décalage initial. La chaîne
       de format est composée de zéro ou plus d'indicateurs : les caractères
       ordinaires (différents de %), qui sont copiés sans modification sur la
       sortie, et les spécifications de conversion, qui chacune recherche un ou
       plus d’arguments suivants. Les spécifications de conversion sont
       introduites par le caractère %, et se terminent par un indicateur de
       conversion. Entre eux peuvent se trouver (dans l'ordre), zéro ou
       plusieurs attributs, une valeur optionnelle de largeur minimale de champ,
       une valeur optionnelle de précision, et un éventuel modificateur de
       longueur.

       Les arguments doivent correspondre correctement (après les promotions de
       types) avec les indicateurs de conversion. Par défaut les arguments sont
       pris dans l'ordre indiqué, où chaque « * » (voir Largeur de champ et
       Précision ci-après) et chaque indicateur de conversion réclame un nouvel
       argument (et l'insuffisance d’arguments est une erreur). On peut aussi
       préciser explicitement quel argument prendre, en écrivant, à chaque
       conversion, « %m$ » au lieu de « % », et « *m$ » au lieu de « * ».
       L'entier décimal m indique la position dans la liste d'arguments,
       l'indexation commençant à 1. Ainsi,

           printf("%*d", width, num);

       et

           printf("%2$*1$d", width, num);

       sont équivalents. La seconde notation permet de répéter plusieurs fois le
       même argument. Le standard C99 n'autorise pas le style utilisant « $ »,
       qui provient des Spécifications UNIX Single. Si le style avec « $ » est
       utilisé, il faut l'employer pour toutes conversions prenant un argument,
       et pour tous les arguments de largeur et de précision, mais on peut le
       mélanger avec des formats « %% » qui ne consomment pas d'arguments. Il ne
       doit pas y avoir de sauts dans les numéros des arguments spécifiés avec
       « $ ». Par exemple, si les arguments 1 et 3 sont spécifiés, l'argument 2
       doit aussi être mentionné quelque part dans la chaîne de format.

       Pour certaines conversions numériques, un caractère de séparation
       décimale (le point par défaut) est utilisé, ainsi qu'un caractère de
       regroupement par milliers. Les véritables caractères dépendent de la
       valeur de LC_NUMERIC dans la locale (consultez setlocale(3)). La
       localisation POSIX utilise « . » comme séparateur décimal, et n'a pas de
       caractère de regroupement. Ainsi,

           printf("%'.2f", 1234567.89);

       s'affichera comme « 1234567.89 » dans la localisation POSIX,
       « 1 234 567,89 » en localisation fr_FR, et « 1.234.567,89 » en
       localisation da_DK.

   Caractères d'attribut
       Le caractère % peut être éventuellement suivi par zéro ou plusieurs des
       attributs suivants :

       #      Indique que la valeur doit être convertie en une autre forme. Pour
              la conversion o le premier caractère de la chaîne de sortie vaudra
              zéro (en ajoutant un préfixe 0 si ce n'est pas déjà un zéro). Pour
              les conversions x et X un résultat non nul reçoit le préfixe
              « 0x » (ou « 0X » pour l'indicateur X). Pour les conversions a, A,
              e, E, f, F, g et G le résultat contiendra toujours un point
              décimal même si aucun chiffre ne le suit (normalement, un point
              décimal n'est présent avec ces conversions que si des décimales le
              suivent). Pour les conversions g et G les zéros en tête ne sont
              pas éliminés, contrairement au comportement habituel. Pour les
              autres conversions, le résultat est indéfini.

       0      Indique le remplissage avec des zéros. Pour les conversions d, i,
              o, u, x, X, a, A, e, E, f, F, g et G, la valeur est complétée à
              gauche par des zéros plutôt que par des espaces. Si les attributs
              0 et - apparaissent ensemble, l'attribut 0 est ignoré. Si une
              précision est fournie avec une conversion numérique (d, i, o, u, x
              et X), l'attribut 0 est ignoré. Pour les autres conversions, le
              comportement est indéfini.

       -      Indique que la valeur convertie doit être justifiée sur la limite
              gauche du champ (par défaut elle l'est à droite). Les valeurs sont
              complétées à droite par des espaces, plutôt qu'à gauche par des
              zéros ou des espaces. Un attribut - surcharge un attribut 0 si les
              deux sont fournis.

       ' '    (une espace) Indique qu'une espace doit être laissée avant un
              nombre positif (ou une chaîne vide) produit par une conversion
              signée

       +      Un signe (+ ou -) doit toujours être imprimé avant un nombre
              produit par une conversion signée. Par défaut, un signe n'est
              utilisé que pour les valeurs négatives. Un attribut + surcharge un
              attribut « espace » si les deux sont fournis.

       Les cinq caractères d'attributs ci-dessus sont définis dans la norme C99,
       les Spécifications UNIX Single en ajoutent un :

       '      Les conversions décimales (i, d, u, f, F, g et G) indiquent que
              les chiffres d'un argument numérique doivent être groupés par
              milliers en fonction de la localisation (consultez setlocale(3)).
              Remarquez que de nombreuses versions de gcc(1) n'acceptent pas cet
              attribut et déclencheront un avertissement (SUSv2 n'inclue pas
              %'F, mais SUSv3 l'a ajouté).

       La glibc 2.2 ajoute un caractère d'attribut supplémentaire.

       I      Pour les conversions décimales (i, d et u), la sortie emploie les
              chiffres de la localisation alternative s'il y en a une. Par
              exemple, depuis la glibc 2.2.3, cela donnera des chiffres arabes
              pour la localisation perse (« fa_IR »).

   Largeur de champ
       Un nombre optionnel ne commençant pas par un zéro, peut indiquer une
       largeur minimale de champ. Si la valeur convertie occupe moins de
       caractères que cette largeur, elle sera complétée par des espaces à
       gauche (ou à droite si l'attribut d'alignement à gauche a été fourni). À
       la place de la chaîne représentant le nombre décimal, on peut écrire
       « * » ou « *m$ » (m étant entier) pour indiquer que la largeur du champ
       est fournie dans l'argument suivant ou dans le m-ième argument
       respectivement. L'argument fournissant la largeur doit être de type int.
       Une largeur négative est considérée comme l'attribut « - » vu plus haut
       suivi d'une largeur positive. En aucun cas une largeur trop petite ne
       provoque la troncature du champ. Si le résultat de la conversion est plus
       grand que la largeur indiquée, le champ est élargi pour contenir le
       résultat.

   Précision
       Une précision optionnelle, sous la forme d'un point (« . ») suivi par une
       chaîne optionnelle de nombres décimaux. À la place de la chaîne
       représentant le nombre décimal, on peut écrire « * » ou « *m$ » (m étant
       entier) pour indiquer que la précision est fournie dans l'argument
       suivant ou dans le m-ième argument respectivement, et qui doit être de
       type int. Si la précision ne contient que le caractère « . », elle est
       considérée comme zéro. Une précision négative est considérée comme omise.
       Cette précision indique un nombre minimal de chiffres à faire apparaître
       lors des conversions d, i, o, u, x et X, le nombre de décimales à faire
       apparaître pour les conversions a, A, e, E, f et F le nombre maximal de
       chiffres significatifs pour g et G et le nombre maximal de caractères à
       imprimer depuis une chaîne pour les conversions s et S.

   Modificateur de longueur
       Ici, une « conversion d’entier » correspond à d, i, o, u, x ou X.

       hh     La conversion d’entier suivante correspond à un signed char ou
              unsigned char, ou la conversion n suivante correspond à un
              pointeur sur un argument signed char.

       h      A following integer conversion corresponds to a short or unsigned
              short argument, or a following n conversion corresponds to a
              pointer to a short argument.

       l      (ell) A following integer conversion corresponds to a long or
              unsigned long argument, or a following n conversion corresponds to
              a pointer to a long argument, or a following c conversion
              corresponds to a wint_t argument, or a following s conversion
              corresponds to a pointer to wchar_t argument.

       ll     (ell-ell).  A following integer conversion corresponds to a long
              long or unsigned long long argument, or a following n conversion
              corresponds to a pointer to a long long argument.

       q      Un synonyme de ll. Il s'agit d'une extension non standard, dérivée
              de BSD ; évitez son utilisation dans du nouveau code.

       L      La conversion a, A, e, E, f, F, g, ou G suivante correspond à un
              argument long double (C99 autorise %LF mais pas SUSv2).

       j      La conversion d’entier suivante correspond à un argument intmax_t
              ou uintmax_t, ou la conversion n suivante correspond à un pointeur
              sur un argument intmax_t.

       z      La conversion d’entier suivante correspond à un argument size_t ou
              ssize_t, ou la conversion n suivante correspond à un pointeur sur
              un argument size_t.

       Z      Un synonyme non standard de z qui précède l'apparition de z. Ne
              pas l'utiliser dans du nouveau code.

       t      La conversion d’entier suivante correspond à un argument
              ptrdiff_t, ou la conversion n suivante correspond à un pointeur
              sur un argument ptrdiff_t.

       SUSv3 mentionne tous les modificateurs précédents à l'exception des
       extensions non standard. Les spécifications SUSv2 ne mentionnent que les
       modificateurs de longueur h (dans hd, hi, ho, hx, hX et hn), l (dans ld,
       li, lo, lx, lX, ln, lc et ls) et L (dans Le, LE, Lf, Lg et LG).

       En tant qu’extension non standard, l'implémentation GNU traite ll et L
       comme des synonymes de façon à ce qu'il soit possible, par exemple,
       d'écrire llg (comme synonyme conforme aux standards de Lg) et Ld (comme
       synonyme conforme aux standards de lld). Une telle utilisation n'est pas
       portable.

   Indicateurs de conversion
       Un caractère indique le type de conversion à apporter. Les indicateurs de
       conversion, et leurs significations sont :

       d, i   L'argument int est converti en un chiffre décimal signé. La
              précision, si elle est mentionnée, correspond au nombre minimal de
              chiffres qui doivent apparaître. Si la conversion fournit moins de
              chiffres, le résultat est rempli à gauche avec des zéros. Par
              défaut la précision vaut 1. Lorsque 0 est converti avec une
              précision valant 0, la sortie est vide.

       o, u, x, X
              L'argument unsigned int est converti en un chiffre octal non signé
              (o), un chiffre décimal non signé (u) ou un chiffre hexadécimal
              non signé (x et X). Les lettres abcdef sont utilisées pour les
              conversions avec x, les lettres ABCDEF sont utilisées pour les
              conversions avec X. La précision, si elle est indiquée, donne un
              nombre minimal de chiffres à faire apparaître. Si la valeur
              convertie nécessite moins de chiffres, elle est complétée à gauche
              avec des zéros. La précision par défaut vaut 1. Lorsque 0 est
              converti avec une précision valant 0, la sortie est vide.

       e, E   L'argument, de type double, est arrondi et présenté avec la
              notation scientifique [-]c.ccce±cc dans lequel se trouve un
              chiffre (qui n'est pas nul si l'argument n'est pas nul) avant le
              point, puis un nombre de décimales égal à la précision demandée.
              Si la précision n'est pas indiquée, l'affichage contiendra
              6 décimales. Si la précision vaut zéro, il n'y a pas de point
              décimal. Une conversion E utilise la lettre E (plutôt que e) pour
              introduire l'exposant. Celui-ci contient toujours au moins deux
              chiffres. Si la valeur affichée est nulle, son exposant est 00.

       f, F   L'argument, de type double, est arrondi et présenté avec la
              notation classique [-]ccc.ccc, où le nombre de décimales est égal
              à la précision réclamée. Si la précision n'est pas indiquée,
              l'affichage se fera avec 6 décimales. Si la précision vaut zéro,
              aucun point n'est affiché. Lorsque le point est affiché, il y a
              toujours au moins un chiffre devant.

              SUSv2 ne mentionne pas F et dit qu'une représentation des chaînes
              de caractères pour l'infini ou NaN devrait être disponible. SUSv3
              ajoute l'indicateur F. La norme C99 précise « [-]inf » ou
              « [-]infinity » pour les infinis, et une chaîne commençant par
              « nan » pour NaN dans le cas d'une conversion f, et les chaînes
              « [-]INF », « [-]INFINITY » ou « NAN* » pour une conversion F.

       g, G   L'argument, de type double, est converti en style f ou e (F ou E
              pour la conversion G). La précision indique le nombre de décimales
              significatives. Si la précision est absente, une valeur par défaut
              de 6 est utilisée. Si la précision vaut 0, elle est considérée
              comme valant 1. La notation scientifique e est utilisée si
              l'exposant est inférieur à -4 ou supérieur ou égal à la précision
              demandée. Les zéros en fin de partie décimale sont supprimés. Un
              point décimal n'est affiché que s'il est suivi d'au moins un
              chiffre.

       a, A   (C99 mais pas SUSv2, mais rajouté dans SUSv3). Pour la conversion
              a, l'argument de type double est transformé en notation
              hexadécimale (avec les lettres abcdef) de forme [-]0xh.hhhhp± ;
              pour la conversion A, le préfixe 0X, les lettres ABCDEF et le
              séparateur d'exposant P sont utilisés. Il y a un chiffre
              hexadécimal avant la virgule et le nombre de chiffres ensuite est
              égal à la précision. La précision par défaut suffit pour une
              représentation exacte de la valeur, si une représentation exacte
              est possible en base 2. Sinon, elle est suffisamment grande pour
              distinguer les valeurs de type double. Le chiffre avant le point
              décimal n'est pas spécifié pour les nombres non normalisés et il
              est non nul mais non spécifié pour les nombres normalisés.

       c      S'il n'y a pas de modificateur l, l'argument, de type int, est
              converti en un unsigned char et le caractère correspondant est
              affiché. Si un modificateur l est présent, l'argument de type
              wint_t (caractère large) est converti en séquence multioctet par
              un appel à wcrtomb(3), avec un état de conversion débutant dans
              l'état initial. La chaîne multioctet résultante est écrite.

       s      S'il n'y a pas de modificateur l, l'argument de type const char *
              est supposé être un pointeur sur un tableau de caractères
              (pointeur sur une chaîne). Les caractères du tableau sont écrits
              jusqu'à l'octet NULL final (« \0 »), non compris. Si une précision
              est indiquée, seul ce nombre de caractères sont écrits. Si une
              précision est fournie, il n'y a pas besoin d'octet NULL. Si la
              précision n'est pas donnée, ou si elle est supérieure à la
              longueur du tableau, l'octet NULL final est nécessaire.

              Si un modificateur l est présent, l'argument de type const
              wchar_t * est supposé être un pointeur sur un tableau de
              caractères larges. Les caractères larges du tableau sont convertis
              en une séquence de caractères multioctets (chacun par un appel de
              wcrtomb(3), avec un état de conversion dans l'état initial avant
              le premier caractère large), cela jusqu'au caractère large NULL
              final compris. Les caractères multioctets résultants sont écrits
              jusqu'à l’octet NULL final (non compris). Si une précision est
              fournie, il n'y a pas plus d'octets écrits que la précision
              indiquée, mais aucun caractère multioctet n'est écrit
              partiellement. Remarquez que la précision concerne le nombre
              d'octets écrits et non pas le nombre de caractères larges ou de
              positions d'écrans. La chaîne doit contenir un caractère large
              NULL final, sauf si une précision est indiquée et est suffisamment
              petite pour que le nombre d'octets écrits la remplisse avant la
              fin de la chaîne.

       C      (Ni dans C99, ni dans C11, mais dans SUSv2, SUSv3 et SUSv4)
              Synonyme de lc. Ne pas utiliser.

       S      (Ni dans C99, ni dans C11, mais dans SUSv2, SUSv3 et SUSv4)
              Synonyme de ls. Ne pas utiliser.

       p      L'argument pointeur, du type void * est affiché en hexadécimal,
              comme avec %#x ou %#lx.

       n      Le nombre de caractères écrits jusqu'à présent est stocké dans
              l'entier pointé par l'argument correspondant. Cet argument doit
              être un int *, ou une variante dont la taille correspond au
              modificateur de longueur d'entier optionnellement fourni. Aucun
              argument n'est converti (cet indicateur n'est pas pris en charge
              par la bibliothèque C Bionic). Le comportement n'est pas défini si
              la spécification de conversion comporte un drapeau, une longueur
              de champ ou une précision.

       m      (extension glibc ; pris en charge par uClibc et musl) Affiche la
              sortie strerror(errno). Aucun argument n'est requis.

       %      Un caractère « % » est écrit. Il n'y a pas de conversion.
              L'indicateur complet est « %% ».

VALEUR RENVOYÉE
       En cas de succès, ces fonctions renvoient le nombre de caractères
       affichés (sans compter l'octet NULL final utilisé pour terminer les
       sorties dans les chaînes).

       Les fonctions snprintf() et vsnprintf() n'écrivent pas plus de taille
       octets (y compris l'octet NULL final). Si la sortie a été tronquée à
       cause de la limite, la valeur de retour est le nombre de caractères
       (octet NULL final non compris) qui auraient été écrits dans la chaîne
       s'il y avait eu suffisamment de place. Ainsi, une valeur de retour taille
       ou plus signifie que la sortie a été tronquée (consultez aussi la section
       NOTES plus bas).

       Si une erreur de sortie s'est produite, une valeur négative est renvoyée.

ATTRIBUTS
       Pour une explication des termes utilisés dans cette section, consulter
       attributes(7).

       ┌────────────────────────────────┬──────────────────────┬────────────────┐
       │Interface                       Attribut             Valeur         │
       ├────────────────────────────────┼──────────────────────┼────────────────┤
       │printf(), fprintf(), sprintf(), │ Sécurité des threads │ MT-Safe locale │
       │snprintf(), vprintf(),          │                      │                │
       │vfprintf(), vsprintf(),         │                      │                │
       │vsnprintf()                     │                      │                │
       └────────────────────────────────┴──────────────────────┴────────────────┘

CONFORMITÉ
       fprintf(), printf(), sprintf(), vprintf(), vfprintf(), vsprintf() :
       POSIX.1-2001, POSIX.1-2008, C89, C99.

       snprintf(), vsnprintf() : POSIX.1-2001, POSIX.1-2008, C99.

       dprintf() et vdprintf() sont originellement des extensions GNU. Elles ont
       été standardisées dans POSIX.1-2008.

       En ce qui concerne la valeur de retour de snprintf(), SUSv2 et C99 sont
       en contradiction : lorsque snprintf() est appelée avec un argument
       taille=0, SUSv2 précise une valeur de retour indéterminée, inférieure à
       1, alors que C99 autorise chaîne à être NULL dans ce cas, et renvoie
       (comme toujours) le nombre de caractères qui auraient été écrits si la
       chaîne de sortie avait été assez grande. Les spécifications de snprintf()
       dans POSIX.1-2001 et ses versions supérieures sont alignées avec C99.

       La bibliothèque glibc 2.1 ajoute les modificateurs de longueur hh, j, t
       et z, et les caractères de conversion a et A.

       La bibliothèque glibc 2.2. ajoute le caractère de conversion F avec la
       sémantique C99, et le caractère d'attribut I.

NOTES
       Certains programmes reposent imprudemment sur du code comme :

           sprintf(buf, "%s texte supplémentaire", buf);

       pour ajouter du texte à buf. Cependant, les normes indiquent
       explicitement que le résultat n'est pas défini si les tampons de source
       et de destination se recouvrent lors d'un appel à sprintf(), snprintf(),
       vsprintf() et vsnprintf(). En fonction de la version de gcc(1) utilisée
       et des options de compilation, ces appels ne produiront pas le résultat
       attendu.

       L'implémentation des fonctions snprintf() et vsnprintf() de la glibc se
       conforme à la norme C99, et se comporte comme décrit plus haut depuis la
       glibc 2.1. Jusqu'à la glibc 2.0.6, elles renvoyaient -1 si la sortie
       avait été tronquée.

BOGUES
       Comme sprintf() et vsprintf() ne font pas de suppositions sur la longueur
       des chaînes, le programme appelant doit s'assurer de ne pas déborder
       l'espace d'adressage. C'est souvent difficile. Notez que la longueur des
       chaînes peut varier avec la localisation et être difficilement
       prévisible. Il faut alors utiliser snprintf() ou vsnprintf() à la place
       (ou encore asprintf(3) et vasprintf(3)).

       Un code tel que printf(toto); indique souvent un bogue, car toto peut
       contenir un caractère « % ». Si toto vient d'une saisie non sécurisée, il
       peut contenir %n, ce qui autorise printf() à écrire dans la mémoire, et
       crée une faille de sécurité.

EXEMPLES
       Pour afficher Pi avec cinq décimales :

           #include <math.h>
           #include <stdio.h>
           fprintf (stdout, "pi = %.5f\n", 4 * atan (1.0));

       Pour afficher une date et une heure sous la forme « Sunday, July 3,
       23:15 », ou jour_semaine et mois sont des pointeurs sur des chaînes :

           #include <stdio.h>
           fprintf(stdout, "%s, %s %d, %.2d:%.2d\n",
                   jour_semaine, mois, jour, heure, minute);

       De nombreux pays utilisent un format de date différent, comme
       jour-mois-année. Une version internationale doit donc être capable
       d'afficher les arguments dans l'ordre indiqué par le format :

           #include <stdio.h>
           fprintf(stdout, format,
                   jour_semaine, mois, jour, heure, min);

       où le format dépend de la localisation et peut permuter les arguments.
       Avec la valeur :

           "%1$s, %3$d. %2$s, %4$d:%5$.2d"

       On peut obtenir « Dimanche, 3 juillet, 23:15 ».

       Pour allouer une chaîne de taille suffisante et écrire dedans (code
       correct aussi bien pour la glibc 2.0 que la glibc 2.1) :

       #include <stdio.h>
       #include <stdlib.h>
       #include <stdarg.h>

       char *
       make_message(const char *fmt, ...)
       {
           int n = 0;
           size_t size = 0;
           char *p = NULL;
           va_list ap;

           /* Determine required size. */

           va_start(ap, fmt);
           n = vsnprintf(p, size, fmt, ap);
           va_end(ap);

           if (n < 0)
               return NULL;

           size = (size_t) n + 1;      /* One extra byte for '\0' */
           p = malloc(size);
           if (p == NULL)
               return NULL;

           va_start(ap, fmt);
           n = vsnprintf(p, size, fmt, ap);
           va_end(ap);

           if (n < 0) {
               free(p);
               return NULL;
           }

           return p;
       }

       En cas de troncature dans les versions de la glibc avant la 2.0.6, c'est
       traité comme une erreur au lieu d'être traité de façon élégante.

VOIR AUSSI
       printf(1), asprintf(3), puts(3), scanf(3), setlocale(3), strfromd(3),
       wcrtomb(3), wprintf(3), locale(5)

COLOPHON
       Cette page fait partie de la publication 5.11 du projet man-pages Linux.
       Une description du projet et des instructions pour signaler des anomalies
       et la dernière version de cette page, peuvent être trouvées à l'adresse
       https://www.kernel.org/doc/man-pages/.


TRADUCTION
       La traduction française de cette page de manuel a été créée par
       Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin
       <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>,
       François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe
       Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-
       luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas
       Huriaux <thomas.huriaux@gmail.com>, Nicolas François
       <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>,
       Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier
       <barbier@debian.org>, David Prévot <david@tilapin.org>, Frédéric Hantrais
       <fhantrais@gmail.com> et Grégoire Scano <gregoire.scano@malloc.fr>

       Cette traduction est une documentation libre ; veuillez vous reporter à
       la GNU General Public License version 3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ concernant les conditions de
       copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de manuel,
       veuillez envoyer un message à debian-l10n-french@lists.debian.org ⟨⟩.




GNU                               22 mars 2021                         PRINTF(3)