Syntaxe de spécification de format : printf et wprintf fonctions

Les différentes fonctions printf et wprintf acceptent une chaîne de format et des arguments facultatifs, et génèrent en sortie une séquence de caractères mise en forme. La chaîne de format contient zéro ou plusieurs directives qui sont soit des caractères littéraux pour la sortie, soit des spécifications de conversion codées qui décrivent comment mettre en forme un argument dans la sortie. Cet article décrit la syntaxe utilisée pour encoder les spécifications de conversion dans la chaîne de format. Pour obtenir la liste de ces fonctions, consultez E/S de flux.

Une spécification de conversion se compose de champs facultatifs et obligatoires mis en forme comme suit :

%[flags][width][.precision][size]type

Chaque champ de la spécification de conversion est un caractère ou un nombre qui représente un spécificateur d’option ou de conversion de format particulier. Le champ obligatoire type spécifie le genre de conversion à appliquer à un argument. Les indicateurs facultatifs, la largeur et les champs de précision contrôlent d’autres aspects de format tels que les espaces de début ou les zéros, la justification et la précision affichée. Le champ size spécifie la taille de l’argument consommé et converti.

Une spécification de conversion de base contient uniquement le symbole de pourcentage et un caractère type. Par exemple, %s spécifie une conversion de chaîne. Pour imprimer un caractère de pourcentage, utilisez %%. Si un signe de pourcentage est suivi d’un caractère qui n’a aucune signification en tant que champ de format, le gestionnaire de paramètres non valides est appelé. Pour plus d’informations, consultez Validation des paramètres.

Important

Pour assurer la sécurité et la stabilité, assurez-vous que les chaînes de spécification de conversion de format ne sont pas définies par l’utilisateur final. Par exemple, imaginez un programme qui invite l'utilisateur à entrer un nom et enregistre l'entrée dans une variable de chaîne nommée user_name. Pour imprimer user_name, ne procédez jamais comme suit :

printf( user_name ); /* Danger! If user_name contains "%s", program will crash */

Procédez plutôt comme suit :

printf( "%s", user_name );

Remarque

Dans Visual Studio 2015, les printf fonctions et scanf la famille de fonctions ont été déclarées comme inline et déplacées vers les en-têtes et <conio.h> les <stdio.h> en-têtes. Si vous migrez du code plus ancien, vous pouvez voir LNK2019 en relation avec ces fonctions. Pour plus d’informations, consultez l’historique des modifications Visual C++ 2003 - 2015.

Spécificateur de conversion de type

Le caractère spécificateur de conversion type précise si l’argument correspondant doit être interprété comme un caractère, une chaîne, un pointeur, un entier ou un nombre à virgule flottante. Le caractère type, qui est le seul champ de spécification de conversion obligatoire, apparaît après tous les champs facultatifs.

Les arguments qui suivent la chaîne de format sont interprétés en fonction du caractère type correspondant et du préfixe size facultatif. Les conversions pour les types de caractères char et wchar_t sont spécifiées à l’aide c ou C, et les chaînes de caractères multioctets et multioctets sont spécifiées à l’aide s ou S, selon la fonction de mise en forme utilisée. Les arguments caractère et chaîne spécifiés par l’utilisation c et s sont interprétés comme char et char* par printf des fonctions de famille, ou comme wchar_t et wchar_t* par wprintf des fonctions de famille. Les arguments caractère et chaîne spécifiés par l’utilisation C et S sont interprétés comme wchar_t et wchar_t* par printf des fonctions de famille, ou comme char et char* par wprintf des fonctions de famille. Ce comportement est spécifique à Microsoft. Pour des raisons historiques, les wprintf fonctions utilisent c et s font référence à wchar_t des caractères et CS spécifient des caractères étroits.

Les types entiers tels que short, , longint, long long, et leurs unsigned variantes, sont spécifiés à l’aide dde , , io, , u, xet X. Les types à virgule flottante tels que , et , sont spécifiés à l’aide ade , , eA, , E, f, F, get G.long doubledoublefloat Par défaut, à moins qu’ils ne soient modifiés par un préfixe de taille , les arguments entiers sont coerced en int type, et les arguments à virgule flottante sont codés sur double. Sur les systèmes 64 bits, il s’agit d’une int valeur 32 bits . Par conséquent, les entiers 64 bits sont tronqués lorsqu’ils sont mis en forme pour la sortie, sauf si un préfixe de taille ou llI64 est utilisé. Les types de pointeurs spécifiés à p l’aide de la taille de pointeur par défaut pour la plateforme.

Remarque

Spécifique à Microsoft :
Le Z caractère de type et le comportement des ccaractères , , sCet S tapez des caractères lorsqu’ils sont utilisés avec les fonctions et wprintf les printf fonctions, sont des extensions Microsoft. La norme ISO C utilise c et s systématiquement pour les caractères et chaînes étroits, ainsi C que S pour les caractères et chaînes larges, dans toutes les fonctions de mise en forme.

Caractères du champ type

Caractère de type Argument Format de sortie
c Caractère Quand il est utilisé avec les fonctions printf, spécifie un caractère codé sur un octet ; quand il est utilisé avec les fonctions wprintf, spécifie un caractère large.
C Caractère Quand il est utilisé avec les fonctions printf, spécifie un caractère large ; quand il est utilisé avec les fonctions wprintf, spécifie un caractère codé sur un octet.
d Entier Entier décimal signé.
i Entier Entier décimal signé.
o Entier Entier octal non signé.
u Entier Entier décimal non signé.
x Entier Entier hexadécimal non signé ; utilise «abcdef ».
X Entier Entier hexadécimal non signé ; utilise «ABCDEF ».
e Virgule flottante Valeur signée qui a le formulaire [-]d.ddde[]dd[dd[+-|d], où d est un chiffre décimal, dddd est un ou plusieurs chiffres décimaux en fonction de la précision spécifiée, ou six par défaut, et dd[d] est de deux ou trois chiffres décimaux en fonction du format de sortie et de la taille de l’exposant.
E Virgule flottante Identique au format, e sauf que plutôt que E d’introduire e l’exposant.
f Virgule flottante Valeur signée qui a le formulaire [-]dddd.d, où dddd est un ou plusieurs chiffres décimaux. Le nombre de chiffres avant la virgule décimale dépend de l’ampleur du nombre, et le nombre de chiffres après la virgule décimale dépend de la précision demandée (ou six par défaut).
F Virgule flottante Identique au format, f sauf que la sortie infini et NaN est capitalisée.
g Virgule flottante Les valeurs signées sont affichées au format ou e au f format, selon la valeur et la précision spécifiées. Le e format est utilisé uniquement lorsque l’exposant de la valeur est inférieur à -4 ou supérieur ou égal à l’argument de précision . Les zéros de droite sont tronqués et la virgule décimale apparaît uniquement si elle est suivie d'un ou plusieurs chiffres.
G Virgule flottante Identique au g format, sauf que, plutôt que Ee, introduit l’exposant (le cas échéant).
a Virgule flottante Valeur à virgule flottante hexadécimale double précision signée qui a la forme []0xh.hhhh[|-+p]dd, où h.hhhhh sont les chiffres hexadécimaux (à l’aide de lettres minuscules) de la mantisse, et dd sont un ou plusieurs chiffres pour l’exposant.- La précision indique le nombre de chiffres après la virgule.
A Virgule flottante Valeur à virgule flottante hexadécimale double précision signée qui a la forme []0Xh.hhhh[|+P-]dd, où h.hhhhh sont les chiffres hexadécimaux (utilisant des lettres majuscules) de la mantisse, et dd sont un ou plusieurs chiffres pour l’exposant.- La précision indique le nombre de chiffres après la virgule.
n Pointeur désignant un entier Nombre de caractères correctement écrits jusqu'à présent dans le flux ou la mémoire tampon. Cette valeur est stockée dans l’entier dont l’adresse est fournie sous forme d’argument. La taille de l’entier désigné par le pointeur peut être contrôlée par un préfixe de spécification de la taille de l’argument. Le spécificateur n est désactivé par défaut ; pour plus d’informations, consultez la remarque importante sur la sécurité.
p Type de pointeur Affichez l’argument sous forme d’adresse en chiffres hexadécimaux.
s String Quand il est utilisé avec les fonctions printf, spécifie une chaîne de caractères codés sur un octet ou multioctets ; quand il est utilisé avec les fonctions wprintf, spécifie une chaîne de caractères larges. Les caractères s’affichent jusqu’au premier caractère Null ou jusqu’à ce que la valeur de precision soit atteinte.
S String Quand il est utilisé avec les fonctions printf, spécifie une chaîne de caractères larges ; quand il est utilisé avec les fonctions wprintf, spécifie une chaîne de caractères codés sur un octet ou multioctets. Les caractères s’affichent jusqu’au premier caractère Null ou jusqu’à ce que la valeur de precision soit atteinte.
Z Structure ANSI_STRING ou UNICODE_STRING VS 2013 et versions antérieures
Lorsque l’adresse d’une ou UNICODE_STRING d’une ANSI_STRING structure est passée en tant qu’argument, affichez la chaîne contenue dans la mémoire tampon pointée par le Buffer champ de la structure. Utilisez un préfixe de modificateur de taille pour w spécifier un UNICODE_STRING argument, par exemple %wZ. Le champ Length de la structure doit indiquer la longueur, en octets, de la chaîne. Le champ MaximumLength de la structure doit indiquer la longueur, en octets, de la mémoire tampon.

Runtime C universel (UCRT)
Il existe un problème connu dans l’UCRT qui est actuellement maintenu pour la compatibilité. Comme le S spécificateur, le Z spécificateur sans préfixe de modificateur de taille fait référence à un UNICODE_STRING moment où vous utilisez une fonction d’impression étroite (par printfexemple) et un ANSI_STRING lors de l’utilisation d’une fonction d’impression large (par wprintfexemple).
Au lieu de Z, utilisez hZ pour spécifier un ANSI_STRING. wZ (ou lZ) peut toujours être utilisé pour spécifier un UNICODE_STRING.

En règle générale, le Z caractère de type est utilisé uniquement dans les fonctions de débogage de pilote qui utilisent une spécification de conversion, comme dbgPrint et kdPrint.

Dans Visual Studio 2015 et versions ultérieures, si l’argument qui correspond à un spécificateur de conversion à virgule flottante (a, , A, efE, , F, g, G) est infini, indéfini ou NaN, la sortie mise en forme est conforme à la norme C99. Ce tableau répertorie les sorties mises en forme :

Value Sortie
Infinité inf
NaN silencieux nan
NaN signalant nan(snan)
Indefinite NaN nan(ind)

L’une de ces chaînes peut être précédée d’un signe. Si un caractère spécificateur de conversion de type virgule flottante est une lettre majuscule, la sortie est également en majuscules. Par exemple, si le spécificateur de format est %F et non %f, un nombre infini apparaît sous la forme INF et non sous la forme inf. Les fonctions scanf peuvent également analyser ces chaînes. Ces valeurs peuvent donc faire l’aller-retour par l’intermédiaire des fonctions printf et scanf.

Avant Visual Studio 2015, le CRT utilisait un autre format non standard pour la sortie des valeurs infinies, indéfinies et NaN :

Value Sortie
+ Infini 1.#INFchiffres aléatoires
-Infini -1.#INFchiffres aléatoires
Indéfini (identique à une valeur NaN silencieuse) chiffre.#INDchiffres aléatoires
NaN chiffre.#NANchiffres aléatoires

L’une de ces chaînes peut avoir été précédée d’un signe et peut avoir été mise en forme différemment en fonction de la largeur et de la précision du champ, parfois avec des effets inhabituels. Par exemple, printf("%.2f\n", INFINITY) les impressions 1.#J parce que la #INF serait « arrondie » à deux chiffres de précision.

Remarque

Si l’argument qui correspond à %s ou %S, ou le champ Buffer de l’argument qui correspond à %Z, est un pointeur Null, « (Null) » s’affiche.

Remarque

Dans tous les formats exponentiels, le nombre par défaut de chiffres d’exposant affichés est de deux (trois si nécessaire). En utilisant la _set_output_format fonction, vous pouvez définir le nombre de chiffres affichés sur trois pour la compatibilité descendante avec le code écrit pour Visual Studio 2013 et avant.

Important

Étant donné que le %n format est intrinsèquement non sécurisé, il est désactivé par défaut. Si %n elle est rencontrée dans une chaîne de format, le gestionnaire de paramètres non valide est appelé, comme décrit dans la validation des paramètres. Pour activer la %n prise en charge, consultez _set_printf_count_output.

Directives d’indicateur

Le premier champ facultatif d’une spécification de conversion contient des directives d’indicateur. Ce champ contient zéro ou plusieurs caractères d’indicateur qui spécifient la justification de sortie et la sortie de contrôle des signes, des vides, des zéros de début, des décimales et des préfixes octal et hexadécimaux. Plusieurs directives d’indicateur peuvent apparaître dans une spécification de conversion, et les caractères d’indicateur peuvent apparaître dans n’importe quel ordre.

Caractères d’indicateur

Indicateur Signification Par défaut
- Aligner à gauche le résultat selon la largeur de champ donnée. Aligner à droite.
+ Utilisez un signe (+ ou -) pour préfixer la valeur de sortie s’il s’agit d’un type signé. Le signe apparaît uniquement pour les valeurs signées négatives (-).
0 Si la largeur est précédée de 0préfixes, les zéros non significatifs sont ajoutés jusqu’à ce que la largeur minimale soit atteinte. Si les deux 0 et - s’affichent, la valeur 0 est ignorée. Si 0 elle est spécifiée pour un format entier (i, u, , Xx, o, d) et une spécification de précision est également présente( par exemple, %04.dl’argument 0 est ignoré). Si 0 elle est spécifiée pour le a format à virgule flottante ou A à virgule flottante, les zéros non significatifs sont ajoutés à la mantisse, après le préfixe ou 0X le 0x préfixe. Aucun remplissage.
espace (' ') Utilisez un vide pour préfixer la valeur de sortie si elle est signée et positive. L’espace est ignoré si l’espace et des indicateurs + apparaissent. Aucun espace ne s’affiche.
# Lorsqu’il est utilisé avec le o, xou X le format, l’indicateur # utilise 0, 0xou , respectivement 0X, pour préfixer n’importe quelle valeur de sortie différente de zéro. Aucun préfixe n’apparaît.
Lorsqu’il est utilisé avec le eformat , , ou aAfFle Eformat, l’indicateur # force la valeur de sortie à contenir un point décimal. La virgule décimale apparaît uniquement si des chiffres la suivent.
Lorsqu’il est utilisé avec le ou G le g format, l’indicateur # force la valeur de sortie à contenir un point décimal et empêche la troncation des zéros de fin.

Ignoré lorsqu’il est utilisé avec c, , di, uou s.
La virgule décimale apparaît uniquement si des chiffres la suivent. Les zéros de fin sont tronqués.

Spécification de largeur

Dans une spécification de conversion, le champ facultatif de spécification de largeur apparaît après n’importe quel caractère d’indicateur. L’argument width est un entier décimal non négatif qui contrôle le nombre minimal de caractères générés. Si le nombre de caractères dans la valeur de sortie est inférieur à la longueur spécifiée, des espaces sont ajoutés à gauche ou à droite des valeurs, selon que l’indicateur d’alignement à gauche (-) est spécifié ou non, jusqu’à ce que la largeur minimale soit atteinte. Si width elle est précédée de 0, les zéros non significatifs sont ajoutés à des conversions en entier ou en virgule flottante jusqu’à ce que la largeur minimale soit atteinte, sauf lorsque la conversion est en infini ou NaN.

La spécification de largeur ne provoque jamais la troncature d’une valeur. Si le nombre de caractères dans la valeur de sortie est supérieur à la largeur spécifiée ou s’il width n’est pas fourni, tous les caractères de la valeur sont de sortie, sous réserve de la spécification de précision.

Si la spécification de la largeur est un astérisque (*), un argument int issu de la liste d’arguments fournit la valeur. L’argument width doit précéder la valeur mise en forme dans la liste d’arguments, comme illustré dans cet exemple :

printf("%0*d", 5, 3); /* 00003 is output */

Une valeur manquante ou petite width dans une spécification de conversion n’entraîne pas la troncation d’une valeur de sortie. Si le résultat d’une conversion est plus large que la width valeur, le champ se développe pour contenir le résultat de conversion.

Spécification de précision

Dans une spécification de conversion, le troisième champ facultatif concerne la spécification de précision. Il se compose d’un point (.) suivi d’un entier décimal non négatif qui, selon le type de conversion, spécifie le nombre de caractères de chaîne, le nombre de décimales ou le nombre de chiffres significatifs à générer.

Contrairement à la spécification de largeur, la spécification de précision peut entraîner la troncation de la valeur de sortie ou l’arrondi d’une valeur à virgule flottante. Si precision elle est spécifiée comme 0 et que la valeur à convertir est 0, le résultat n’est pas de sortie de caractères, comme illustré dans cet exemple :

printf( "%.0d", 0 ); /* No characters output */

Si la spécification de précision est un astérisque (*), un argument int issu de la liste d’arguments fournit la valeur. Dans la liste d’arguments, l’argument precision doit précéder la valeur mise en forme, comme illustré dans cet exemple :

printf( "%.*f", 3, 3.14159265 ); /* 3.142 output */

Le type caractère détermine l’interprétation ou precision la précision par défaut lorsqu’elle precision est omise, comme indiqué dans le tableau suivant.

Comment les valeurs de précision affectent le type

Type Signification Par défaut
a, A La précision indique le nombre de chiffres après la virgule. La précision par défaut s’élève à 13. Si la précision a la valeur 0, aucune virgule décimale n’est imprimée, sauf si l’indicateur # est utilisé.
c, C La précision n’a aucun effet. Le caractère est imprimé.
d, i, o, u, x, X La précision indique le nombre minimal de chiffres à imprimer. Si le nombre de chiffres dans l’argument est inférieur à precision, la valeur de sortie est remplie à gauche de zéros. La valeur n’est pas tronquée lorsque le nombre de chiffres dépasse la précision. La précision par défaut s’élève à 1.
e, E La précision indique le nombre de chiffres à imprimer après la virgule décimale. Le dernier chiffre imprimé est arrondi. La précision par défaut s’élève à 6. Si la précision est 0 ou que la période (.) apparaît sans nombre suivant, aucun point décimal n’est imprimé.
f, F La valeur de précision indique le nombre de chiffres après la virgule décimale. Si une virgule décimale apparaît, au moins un chiffre apparaît devant. La valeur est arrondie au nombre approprié de chiffres. La précision par défaut s’élève à 6. Si la précision est 0 ou si la période (.) apparaît sans nombre suivant, aucun point décimal n’est imprimé.
g, G La précision indique le nombre maximal de chiffres significatifs imprimés. Six chiffres significatifs sont imprimés et tous les zéros de fin sont tronqués.
s, S La précision indique le nombre maximal de caractères à imprimer. Les caractères au-delà de precision ne sont pas imprimés. Les caractères sont imprimés jusqu’à ce qu’un caractère null soit trouvé.

Spécification de taille d’argument

Dans une spécification de conversion, le champ size est un modificateur de longueur d’argument pour le spécificateur de conversion type. Le champ de taille préfixe le champ de type (hh , h, j( l minusculeS L), L, llwt, z( I majuscules i), I32et I64— spécifie la « taille » de l’argument correspondant ( long ou court, 32 bits ou 64 bits, caractère à octet unique ou large) en fonction du spécificateur de conversion qu’ils modifient. Ces préfixes de taille sont utilisés avec les caractères de type dans les familles printf et wprintf de fonctions pour spécifier l’interprétation des tailles d’argument, comme illustré dans le tableau suivant. Le champ size est facultatif pour certains types d’arguments. Si aucun préfixe de taille n’est spécifié, le formateur consomme les arguments d’entier (par exemple char, short, int, long signé ou non signé, ainsi que les types d’énumération) en tant que types int 32 bits, tandis que les arguments à virgule flottante float, double et long double sont consommés en tant que types double 64 bits. Ce comportement correspond aux règles de promotion d’argument par défaut pour les listes d’arguments de variable. Pour plus d’informations sur la promotion des arguments, consultez Ellipsis et Arguments par défaut dans les expressions Postfix. Sur les systèmes 32 bits et 64 bits, la spécification de conversion d’un argument entier 64 bits doit inclure un préfixe de taille de ll ou I64. Sinon, le comportement du formateur n'est pas défini.

Certains types sont de tailles différentes en code 32 bits et 64 bits. Par exemple, la longueur de size_t est 32 bits dans le code compilé pour x86, contre 64 bits dans le code compilé pour x64. Pour créer un code de mise en forme indépendant de la plateforme pour les types de largeur variable, vous pouvez utiliser un modificateur de taille d’argument de largeur variable. Au lieu de cela, utilisez un modificateur de taille d’argument 64 bits et encouragez explicitement le type d’argument de largeur variable à 64 bits. Le modificateur de taille d’argument spécifique à I Microsoft (majuscule i) gère les arguments entiers de largeur variable, mais nous recommandons les modificateurs spécifiques jtau type et z les modificateurs pour la portabilité.

Préfixes de taille pour les spécificateurs de format printf et wprintf

Pour spécifier Utilisez le préfixe Avec le spécificateur de type
char
unsigned char
hh d, i, o, u, x ou X
short int
short unsigned int
h d, i, o, u, x ou X
__int32
unsigned __int32
I32 d, i, o, u, x ou X
__int64
unsigned __int64
I64 d, i, o, u, x ou X
intmax_t
uintmax_t
j ou I64 d, i, o, u, x ou X
long double l (L minuscule) ou L a, A, e, E, f, F, g ou G
long int
long unsigned int
l (L minuscule) d, i, o, u, x ou X
long long int
unsigned long long int
ll (LL minuscule) d, i, o, u, x ou X
ptrdiff_t t ou I (majuscule i) d, i, o, u, x ou X
size_t z ou I (majuscule i) d, i, o, u, x ou X
Caractère codé sur un octet h c ou C
Caractère large l (L minuscule) ou w c ou C
Chaîne de caractères codés sur un octet h s, S ou Z
Chaîne de caractères larges l (L minuscule) ou w s, S ou Z

Les types ptrdiff_t et size_t sont __int32 et unsigned __int32 sur les plateformes 32 bits, et __int64 ou unsigned __int64 sur les plateformes 64 bits. Les I préfixes (majuscules i), jet ztde taille prennent la largeur d’argument correcte pour la plateforme.

Dans Visual C++, bien que long double soit un type distinct, il possède la même représentation interne que double.

Un hc spécificateur ou hC un spécificateur de type est synonyme c de fonctions printf et de C fonctions wprintf . Un spécificateur de type , ou wcwC un lClcspécificateur de type est synonyme C de fonctions printf et de cwprintf fonctions. Un hs spécificateur ou hS un spécificateur de type est synonyme s de fonctions printf et de S fonctions wprintf . Un lsspécificateur , ou wslSwS spécificateur de type est synonyme S de fonctions printf et de swprintf fonctions.

Remarque

Spécifique à Microsoft :
Les I préfixes de modificateur (majuscules i), I32, I64et w de taille d’argument sont des extensions Microsoft et ne sont pas compatibles ISO C. Le h préfixe lorsqu’il est utilisé avec des données de type char et le l préfixe (L minuscule) lorsqu’il est utilisé avec des données de type double sont des extensions Microsoft.

Voir aussi

printf, _printf_l, wprintf, _wprintf_l
printf_s, _printf_s_l, wprintf_s, _wprintf_s_l
printf_p Paramètres positionnels