printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf,
- Provided by: manpages-fr-dev (Version: 3.65d1p1-1)
- Source: manpages-fr
- Report a bug
#include <stdio.h>
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format,
...);
int sprintf(char *str, const char *format,
...);
int snprintf(char *str, size_t size, const char
*format, ...);
#include <stdarg.h>
int vprintf(const char *format, va_list
ap);
int vfprintf(FILE *stream, const char *format,
va_list ap);
int vsprintf(char *str, const char *format,
va_list ap);
int vsnprintf(char *str, size_t size, const
char *format, va_list ap);
Exigences de macros de test de fonctionnalités pour la glibc (consultez
feature_test_macros(7)) :
snprintf(), vsnprintf() :
Les fonctions de la famille printf() produisent des sorties en accord avec le format décrit plus bas. Les fonctions printf() et vprintf() écrivent leur sortie sur stdout, le flux de sortie standard. fprintf() et vfprintf() écrivent sur le flux stream indiqué. sprintf(), snprintf(), vsprintf() et vsnprintf() écrivent leurs sorties dans la chaîne de caractères str.
Les fonctions snprintf() et vsnprintf() écrivent au plus size octets (octet nul (« \0 ») final compris) dans str.
Les fonctions vprintf(), vfprintf(), vsprintf(), vsnprintf() sont équivalentes aux fonctions printf(), fprintf(), sprintf(), 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 appèlent la macro va_arg, la valeur de ap n'est pas définie après l'appel. Consultez stdarg(3).
Ces huit fonctions créent 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.
En cas de succès, ces fonctions renvoient le nombre de caractères affichés (sans compter l'octet nul final utilisé pour terminer les sorties dans les chaînes).
Les fonctions snprintf() et vsnprintf() n'écrivent pas plus de size octets (y compris l'octet nul final). Si la sortie a été tronquée à cause de la limite, la valeur de retour est le nombre de caractères (octet nul final non compris) qui auraient été écrits dans la chaîne s'il y avait eu suffisamment de place. Ainsi, une valeur de retour size 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.
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 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 sont mises en correspondance avec les 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 minimal 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
« * » et chaque indicateur de conversion
réclament un nouvel argument (et où l'insuffisance en
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);
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 Single UNIX. 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 localisation
LC_NUMERIC. La localisation POSIX utilise
« . » comme séparateur décimal, et
n'a pas de caractère de regroupement. Ainsi,
printf("%'.2f", 1234567.89);
Le caractère % peut être éventuellement suivi par un ou plusieurs attributs suivants :
Les cinq caractères d'attributs ci-dessus sont définis dans le standard C, les spécifications SUSv2 en ajoute un :
La glibc 2.2 ajoute un caractère d'attribut supplémentaire.
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é 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.
Une précision éventuelle, sous la forme d'un point (« . ») suivi par un nombre. À 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. L'argument fournissant la précision doit être de type int. Si la précision ne contient que le caractère « . », elle est considérée comme nulle. 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.
Ici, une conversion entière correspond à d, i, o, u, x ou X.
Les spécifications SUSv2 ne mentionnent que les modificateurs de longueur h (dans hd, hi, ho, hx, hX, hn), l (dans ld, li, lo, lx, lX, ln, lc, ls) et L (dans Le, LE, Lf, Lg, LG).
Un caractère indique le type de conversion à apporter. Les indicateurs de conversion, et leurs significations sont :
SUSv2 ne mentionne pas F et dit qu'il existe une chaîne de caractères représentant l'infini ou NaN. Le standard 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 » « NAN* » pour une conversion F.
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), ceci jusqu'au caractère large nul final compris. Les caractères multioctets résultants sont écris jusqu'à l'octet nul 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 nul final, sauf si une précision est indiquée, suffisamment petite pour que le nombre d'octets écrits la remplisse avant la fin de la chaîne.
Les fonctions fprintf(), printf(), sprintf(), vprintf(), vfprintf() et vsprintf() sont conformes à C89 et C99. Les fonctions snprintf() et vsnprintf() sont conformes à C99.
En ce qui concerne la valeur de retour de snprintf(), SUSv2 et C99 sont en contradiction : lorsque snprintf() est appelée avec un argument size=0 SUSv2 précise une valeur de retour indéterminée, inférieure à 1, alors que C99 autorise str à être NULL dans ce cas, et réclame en valeur de retour (comme toujours) le nombre de caractères qui auraient été écrits si la chaîne de sortie avait été assez grande.
La bibliothèque libc4 de Linux connaissait les 5 attributs standards du C. Elle connaissait les modificateurs de longueur h, l, L et les conversions c, d, e, E, f, F, g, G, i, n, o, p, s, u, x et X, où F était synonyme de f. De plus, elle acceptait D, O et U comme synonymes de ld, lo et lu (ce qui causa de sérieux bogues par la suite lorsque le support de %D disparut). Il n'y avait pas de séparateur décimal dépendant de la localisation, pas de séparateur des milliers, pas de NaN ou d'infinis, et pas de « %m$ » ni « *m$ ».
La bibliothèque libc5 de Linux connaissait les 5 attributs standards C, l'attribut « ' », la localisation, « %m$ » et « *m$ ». Elle connaissait les modificateurs de longueur h, l, L, Z et q, mais acceptait L et q pour les long double et les long long int (ce qui est un bogue). Elle ne reconnaissait plus F, D, O et U, mais ajoutait le caractère de conversion m, qui affiche strerror(errno).
La bibliothèque glibc 2.0 ajouta les caractères de conversion C et S.
La bibliothèque glibc 2.1 ajouta les modificateurs de longueur hh, t et z, et les caractères de conversion a et A.
La bibliothèque glibc 2.2. ajouta le caractère de conversion F avec la sémantique C99, et le caractère d'attribut I.
Certains programmes reposent imprudemment sur du code comme :
sprintf(buf, "%s some further text", 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 au standard 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.
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)).
La libc4.[45] de Linux n'avait pas snprintf(), mais proposait une bibliothèque libbsd qui contenait un snprintf() équivalent à sprintf(), c'est-à-dire qui ignorait l'argument size. Ainsi, l'utilisation de snprintf() avec les anciennes libc4 pouvait conduire à de sérieux problèmes de sécurité.
Un code tel que printf(foo); indique souvent un bogue, car foo peut contenir un caractère « % ». Si foo 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é.
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\n"
On peut obtenir « Dimanche, 3 Juillet, 23:15 ».
Pour allouer une chaîne de taille suffisante et écrire dedans (code correct aussi bien pour glibc 2.0 que glibc 2.1) :
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
char *
make_message(const char *fmt, ...)
{
int n;
int size = 100; /* Supposons que nous n'avons pas besoin de plus de 100 octets */
char *p, *np;
va_list ap;
p = malloc(size);
if (p == NULL)
return NULL;
while (1) {
/* Essayons d'écrire dans l'espace alloué */
va_start(ap, fmt);
n = vsnprintf(p, size, fmt, ap);
va_end(ap);
/* Vérifie le code d'erreur */
if (n < 0) {
free(p);
return NULL;
}
/* Si cela fonctionne, renvoie la chaîne */
if (n < size)
return p;
/* Sinon, essayons encore avec plus de place */
size = n + 1; /* Exactement ce qui est nécessaire */
np = realloc(p, size);
if (np == NULL) {
free(p);
return NULL;
} else {
p = np;
}
}
}
En cas de troncature dans les versions de glibc avant 2.0.6, c'est traité comme une erreur au lieu d'être traité de façon élégante.
printf(1), asprintf(3), dprintf(3), scanf(3), setlocale(3), wcrtomb(3), wprintf(3), locale(5)
Cette page fait partie de la publication 3.65 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies peuvent être trouvées à l'adresse http://www.kernel.org/doc/man-pages/.
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>.
Christophe Blaess <http://www.blaess.fr/christophe/> (1996-2003), Alain Portal <http://manpagesfr.free.fr/> (2003-2006). Nicolas François et l'équipe francophone de traduction de Debian (2006-2009).
Veuillez signaler toute erreur de traduction en écrivant à <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le paquet manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « man -L C <section> <page_de_man> ».