table of contents
PRINTF(3) | Manuel du programmeur Linux | PRINTF(3) |
NOM¶
printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf - Formatage des sortiesSYNOPSIS¶
#include <stdio.h>Exigences de macros de test de fonctionnalités pour la glibc (consultez feature_test_macros(7)) :
_BSD_SOURCE ||
_XOPEN_SOURCE >= 500 || _ISOC99_SOURCE ||
_POSIX_C_SOURCE >= 200112L
ou cc -std=c99
DESCRIPTION¶
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)).VALEUR RENVOYÉE¶
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).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 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.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 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.
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ÈRE D'ATTRIBUT¶
Le caractère % peut être éventuellement suivi par un ou plusieurs 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 une valeur non nulle 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, cet attribut n'a pas d'effet.
- 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 avec des zéros plutôt qu'avec 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 doit être justifiée sur la limite gauche du champ (par défaut elle l'est à droite). Sauf pour la conversion n, les valeurs sont complétées à droite par des espaces, plutôt qu'à gauche par des zéros ou des blancs. Un attribut - surcharge un attribut 0 si les deux sont fournis.
- ' '
- (un espace) indique qu'un espace doit être laissé 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 des valeurs négatives. Un attribut + surcharge un attribut « espace » si les deux sont fournis.
- '
- Pour les conversions décimales (i, d, u, f, F, g, G) indique que les chiffres d'un argument numérique doivent être groupés par milliers en fonction de la localisation. Remarquez que de nombreuses versions de gcc(1) n'acceptent pas cet attribut et déclencheront un avertissement (warning). SUSv2 n'inclue pas %'F.
- I
- Pour les conversions décimales (i, d, u) la sortie emploie les chiffres alternatifs de la localisation s'il y en a. 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é 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 é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 « . », ou une valeur négative, elle est considérée comme nulle. 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 entière correspond à d, i, o, u, x ou X.- hh
- La conversion entière suivante correspond à un signed char ou unsigned char, ou la conversion n suivante correspond à un argument pointeur sur un signed char.
- h
- La conversion entière suivante correspond à un short int ou unsigned short int, ou la conversion n suivante correspond à un argument pointeur sur un short int.
- l
- (elle) La conversion entière suivante correspond à un long int ou unsigned long int, ou la conversion n suivante correspond à un pointeur sur un long int, ou la conversion c suivante correspond à un argument wint_t, ou encore la conversion s suivante correspond à un pointeur sur un wchar_t.
- ll
- (elle-elle) La conversion entière suivante correspond à un long long int, ou unsigned long long int, ou la conversion n suivante correspond à un pointeur sur un long long int.
- L
- La conversion a, A, e, E, f, F, g, ou G suivante correspond à un argument long double (C99 autorise %LF mais pas SUSv2).
- q
- (« quad » BSD 4.4 et Linux sous libc5 seulement, ne pas utiliser) Il s'agit d'un synonyme pour ll.
- j
- La conversion entière suivante correspond à un argument intmax_t ou uintmax_t.
- z
- La conversion entière suivante correspond à un argument size_t ou ssize_t (la bibliothèque libc5 de Linux proposait l'argument Z pour cela, ne pas utiliser).
- t
- La conversion entière suivante correspond à un argument ptrdiff_t.
INDICATEUR 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), 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 réel, de type double, est arrondi et présenté avec la notation scientifique [-]c .ccce±cc dans lequel se trouve un chiffre 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 réel, 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.
- g, G
- L'argument réel, de type double, est converti en style f ou e (ou 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). Pour la conversion a, l'argument de type double est transformé en notation hexadécimale (avec les lettres abcdef) [-] 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 pour les nombres normalisés.
- c
- S'il n'y a pas de modificateur l, l'argument entier, 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 nul
(« \0 ») final, 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 de caractère nul. Si
la précision n'est pas donnée, ou si elle est supérieure
à la longueur de la chaîne, le caractère nul final est
nécessaire.
- C
- (dans SUSv2 mais pas dans C99) Synonyme de lc. Ne pas utiliser.
- S
- (dans SUSv2 mais pas dans C99) 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 déjà écrits est stocké dans l'entier indiqué par l'argument pointeur de type int *. Aucun argument n'est converti.
- m
- (extension glibc) 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 « %% ».
CONFORMITɶ
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.NOTES¶
Certains programmes reposent imprudemment sur du code comme :sprintf(buf, "%s some further text", buf);
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)). 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é.EXEMPLE¶
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; if ((p = malloc(size)) == 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); /* Si cela fonctionne, renvoie la chaîne. */ if (n > -1 && n < size) return p; /* Sinon, essayons encore avec plus de place. */ if (n > -1) /* glibc 2.1 */ size = n+1; /* exactemen ce qui est nécessaire */ else /* glibc 2.0 */ size *= 2; /* double la taille */ if ((np = realloc (p, size)) == NULL) { free(p); return NULL; } else { p = np; } } }
VOIR AUSSI¶
printf(1), asprintf(3), dprintf(3), scanf(3), setlocale(3), wcrtomb(3), wprintf(3), locale(5)COLOPHON¶
Cette page fait partie de la publication 3.44 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/>.TRADUCTION¶
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> ».28 septembre 2011 | GNU |