Les flux d'entrées-sorties standards sont limités aux manipulations sur
des caractères codés en ASCII. Cette limitation est très
contraignante lorsque l'on cherche à formater l'affichage de valeurs
numériques. C'est pour dépasser ces contraintes que l'on a introduit deux
fonctions dédiées à la «traduction» entre valeurs numériques et chaînes de
caractères. La fonction printf sert à formater les sorties
sur le flux stdout et la fonction
scanf sert à formater les entrées reçues sur le flux
stdin.
Les prototypes génériques de ces deux fonctions se présentent sous la forme :
scanf(control, arg1, arg2, ...) printf(control, arg1, arg2, ...)
control est une chaîne de caractère qui sert à mettre
en forme les arguments. Cette chaîne peut contenir des caractères
«ordinaires» qui sont recopiés directement depuis ou vers le flux
d'entrée-sortie standard et des formats de conversion positionnés dans la
chaîne à l'aide du caractère balise % suivi du format
choisi.
Les arguments arg1, arg2, ..., doivent correspondre à
chaque caractère % placé dans la chaîne
control.
Le caractère % est une balise de positionnement suivie d'une
spécification de traduction dont le prototype est :
%[indicateur][largeur][.precision][modification]type.
Tous les champs notés entre crochets sont optionnels.
Spécifications du champ obligatoire type :
Tableau 4. Types de conversion
type
|
signification |
|---|---|
%c
|
caractère |
%s
|
chaîne de caractères |
%d
|
nombre entier en décimal |
%e
|
nombre réel sous la forme mantisse/exposant
[-]m.nnnnnne[+|-]xx |
%E
|
nombre réel sous la forme mantisse/exposant en majuscule
[-]m.nnnnnnE[+|-]xx |
%f
|
nombre réel sous la forme [-]mmm.nnnnnn |
%g
|
nombre réel sous la forme la plus courte entre les types
%e et %f |
%G
|
nombre réel sous la forme la plus courte entre les types
%E et %f |
%o
|
nombre entier en octal |
%p
|
pointeur ou adresse de la valeur numérique |
%u
|
nombre entier non signé en décimal |
%x
|
nombre entier en hexadécimal |
%X
|
nombre entier en hexadécimal ; lettres affichées en majuscules |
Spécifications du champ optionnel
[indicateur] :
Tableau 5. Indicateur d'affichage
[indicateur]
|
signification |
|---|---|
-
|
alignement à gauche pour la largeur donnée |
+
|
affichage forcé du signe de la valeur numérique |
espace
|
insertion d'un caractère d'espacement si la valeur numérique est positive |
#
|
affichage précédé de 0, 0x ou
0X avec les types respectifs o, x ou
X |
force l'affichage du point décimal avec les types e,
E et f même si la partie décimale ne contient que
des zéros |
|
force l'affichage du point décimal avec les types g
et G sans supprimer les zéros inutiles |
Spécifications du champ optionnel
[largeur] :
Tableau 6. Largeur de l'affichage
[largeur]
|
signification |
|---|---|
| nombre | nombre minimum de caractères à afficher ; ajout de caractères d'espacement si la valeur est plus «courte» que l'affichage demandé |
0nombre |
idem ci-dessus ; ajout de caractères 0 si la valeur est
plus «courte» que l'affichage demandé |
*nombre |
la largeur n'est pas spécifiée dans la chaîne
control mais par un entier précédent l'argument à
afficher |
Spécifications du champ optionnel
[precision] :
Tableau 7. Precision de l'affichage
[precision]
|
signification |
|---|---|
.nombre |
pour les types d, i, o,
u, x et X : nombre minimum de
chiffres décimaux à afficher ; ajout de caractères d'espacement si la
valeur est plus «courte» que l'affichage demandé |
pour les types e, E et
f : nombre de chiffres à afficher après le point
décimal |
|
pour les types g et G : nombre
maximum de chiffres significatifs à afficher |
|
pour le type s : nombre maximum de caractères à
afficher |
|
pour le type c : pas d'effet |
Spécifications du champ optionnel
[modification] :
Tableau 8. Modification de l'affichage
[modification]
|
signification |
|---|---|
h
|
argument traité comme un entier court (short) |
l
|
argument traité comme un entier long pour les types entiers (long) ou comme un réel double pour les types réels (double) |
L
|
argument traité comme un réel long double |
Voici deux programmes d'illustration de sorties formatées avec la fonction
printf. Le premier bénéficie du jeu de définitions complet
sur GNU/Linux. Le second, exécuté sur un microcontrôleur
MSC1210 et compilé avec SDCC, ne dispose que d'un jeu de
définitions de formats plus restreint.
Exemple 11. Sorties formatées avec printf sur GNU/Linux avec
GCC
01: /* $Id: gcc_printf.c 1129 2007-05-07 15:07:52Z latu $ */
02:
03: #include <stdio.h>
04:
05: #define M_PI 3.14159265358979323846 /* pi */
06:
07: #define YEAR 2007
08:
09: int main() {
10:
11: printf ("Caracteres : %c %c %c %c\n", 'a', 65, 0x30, '0');
12: printf ("Entiers : %d %ld\n", YEAR, 650000);
13: printf ("Affichage avec espaces : |%10d|\n", YEAR);
14: printf ("Affichage avec zeros : |%010d|\n", YEAR);
15: printf ("Differentes bases : %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
16: printf ("Reels : |%4.2f| |%+.4e| |%E|\n", M_PI, M_PI*YEAR, M_PI);
17: printf ("Largeur en argument : |%*d|\n", 5, 10);
18: printf ("%s\n", "Debian GNU/Linux");
19: return 0;
20: }
Voici un exemple d'exécution du programme gcc_printf.c :
$ ./gcc_printf.out Caracteres : a A 0 0 Entiers : 2007 650000 Affichage avec espaces : | 2007| Affichage avec zeros : |0000002007| Differentes bases : 100 64 144 0x64 0144 Reels : |3.14| |+6.3052e+03| |3.141593E+00| Largeur en argument : | 10| Debian GNU/Linux
Par défaut, le support des nombres réels est désactivé dans la chaîne de développement SDCC. Il est nécessaire de passer par une recompilation manuelle des outils de compilation pour obtenir le résultat ci-dessous. Voir Section 13.3, « C sur MSC1210 : SDCC ».
Exemple 12. Sorties formatées avec printf sur un
microcontrôleur MSC1210 avec SDCC
01: #define YEAR 2007
02:
03: void putchar(char c) {
04: ser_putc(c);
05: }
06:
07: int main() {
08:
09: autobaud();
10: EA = 1;
11:
12: printf ("Caracteres : %c %c %c %c\n\r", 'a', 65, 0x30, '0');
13: printf ("Entiers : %d %ld\n\r", YEAR, 650000);
14: printf ("Affichage avec espaces : |%10d|\n\r", YEAR);
15: printf ("Affichage avec zeros : |%010d|\n\r", YEAR);
16: printf ("Differentes bases : %d %x %o %#x %#o \n\r", 100, 100, 100, 100, 100);
17: printf ("Reels : |%f| |%+.4f| |%e|\n\r", M_PI, M_PI*YEAR, M_PI);
18: printf ("Largeur en argument : |%*d|\n\r", 5, 10);
19: printf ("%s\n\r", "Debian GNU/Linux");
20: return 0;
21: }
Voici un exemple d'exécution du programme sdcc_printf.c :
MSC1210 Ver:000305F10 >M0000 ok >M8000 ok >E >T > >Caracteres : a A 0 0 Entiers : 2007 650000 Affichage avec espaces : | 2007| Affichage avec zeros : |0000002007| Differentes bases : 100 64 144 #x #o Reels : |3.141593| |+6305.1762| |E| Largeur en argument : |*d| Debian GNU/Linux
La copie d'écran ci-dessus montre que toutes les options de formatage des sorties ne sont pas supportées par la bibliothèque standard implantée dans la chaîne de développement SDCC. C'est une situation classique, sachant qu'un système spécialisé n'est pas fait pour réaliser une interface utilisateur.
Tableau 9. Caractères spéciaux
| Séquence d'échappement | signification |
|---|---|
| %% | affichage du caractère '%' |
| \0 | caractère null ; valeur 0, délimiteur de fin de chaîne de caractères |
| \a | alerte ; beep système |
| \b | backspace ; déplacement du curseur d'un caractère en arrière |
| \f | form feed ; saut de page |
| \n | new line ; saut de ligne |
| \r | carriage return ; retour chariot |
| \t | tabulation horizontale |
| \v | tabulation verticale |
| \\ | affichage du caractère '\' |
| \' | affichage du caractère ''' |
| \" | affichage du caractère '"' |
| \Onn | affichage de la valeur nn en octal |
| \Xnn | affichage de la valeur nn en hexadécimal |
Vous êtes ici :