Next: Récréation
Up: Les entrées-sorties
Previous: Lecture et écriture par
Sous-sections
La fonction
fprintf admet un nombre variable de paramètres.
Son utilisation est la suivante :
fprintf ( flot-de-données , format , param1 , param2 , ... , paramn )
- -
- flot-de-données est de type pointeur vers FILE.
Il pointe vers le fichier sur lequel se fait l'écriture.
- -
- format est une chaîne de caractères qui spécifie ce qui doit être écrit.
- -
- parami est une expression délivrant une valeur à écrire.
La fonction
fprintf retourne le nombre de caractères écrits, ou une
valeur négative si il y a eu une erreur d'entrée-sortie.
La chaîne
format contient des caractères ordinaires (c'est à dire
différents du caractère
%) qui doivent être copiés tels quels,
et des séquences d'échappement (introduites par le caractère
%),
décrivant la manière dont doivent être écrits
les paramètres
param1,
param2, ...
paramn.
Si il y a moins de parami que n'en réclame le format, le
comportement n'est pas défini.
Si il y a davantage de parami que n'en nécessite le format,
les parami en excès sont évalués, mais leur valeur est ignorée.
Une séquence d'échappement se compose des éléments suivants :
- 1
- Un certain nombre (éventuellement zéro) d'indicateurs
pouvant être les caractères suivants :
- -
- parami sera cadré à gauche dans son champ
d'impression.
- +
- si parami est un nombre signé, il sera
imprimé précédé du signe + ou -.
- blanc
- si parami est un nombre signé et
si son premier caractère n'est pas un signe, on imprimera un blanc
devant parami.
Si on a à la fois l'indicateur + et l'indicateur blanc,
ce dernier sera ignoré.
- #
- cet indicateur demande l'impression de
parami sous une forme non standard.
Pour le format o, cet indicateur force la précision à être
augmentée de manière à ce que parami soit imprimé en commençant
par un zéro.
Pour les formats x et X, cet indicateur a pour but de faire
précéder parami respectivement de 0x ou 0X, sauf si
parami est nul.
Pour les formats e, E, f, g et G, cet
indicateur force parami à être imprimé avec un point décimal,
même si il n'y a aucun chiffre après.
Pour les formats g et G, cet indicateur empêche les zéros de la
fin d'être enlevés.
Pour les autres formats, le comportement n'est pas défini.
- 0
- pour les formats d, i, o, u,
x, X, e, E, f, g, et G cet
indicateur a pour effet de compléter l'écriture de parami avec
des 0 en tête, de manière à ce qu'il remplisse tout son champ
d'impression.
Si il y a à la fois les deux indicateurs 0 et -, l'indicateur
0 sera ignoré.
Pour les formats d, i, o, u, x et X,
si il y a une indication de précision, l'indicateur 0 est ignoré.
Pour les autres formats, le comportement n'est pas défini.
- 2
- Un nombre entier décimal (optionnel) indiquant la taille
minimum du champ d'impression, exprimée en caractères.
Si parami s'écrit sur un nombre de caractères inférieur à cette
taille, parami est complété à droite ou à gauche (selon que l'on
aura utilisé ou pas l'indicateur -), avec des blancs ou des 0,
comme il a été expliqué plus haut.
- 3
- Une indication (optionnelle) de précision, qui donne :
- -
- le nombre minimum de chiffres pour les formats d, i,
o, u, x et X.
- -
- le nombre de chiffres après le point décimal pour les formats e,
E et f.
- -
- le nombre maximum de chiffres significatifs pour les formats g et
G
- -
- le nombre maximum de caractères pour le format s.
Cette indication de précision prend la forme d'un point (.
) suivi
d'un nombre décimal optionnel. Si ce nombre est omis, la précision est prise
égale à 0.
Remarque
Le nombre entier décimal indiquant la taille maximum du champ
d'impression et/ou le nombre entier décimal indiquant la précision,
peuvent être remplacées par le caractère
*.
Si le caractère
* a été utilisé une seule fois dans le format,
la valeur correspondante (taille du champ ou précision) sera prise égale
à
parami-1.
Si le caractère
* a été utilisé deux fois, la taille du champ
d'impression sera égale à
parami-2, et la précision sera
égale à
parami-1.
Si la taille maximum du champ d'impression a une valeur négative, cela
a la sémantique de l'indicateur
-
suivi de la valeur (positive) de la
taille du champ d'impression.
Si la précision est négative, cela a la sémantique d'une précision absente.
- 4
- un caractère optionnel, qui peut être :
- h
- s'appliquant aux formats d, i, o,
u, x ou X : parami sera interprété comme un
short int ou unsigned short int.
- h
- s'appliquant au format n : parami sera
interprété comme un pointeur vers un short int.
- l
- 5.2.
s'appliquant aux formats d, i, o, u, x ou
X : parami sera interprété comme un long int ou un
unsigned long int.
- l
- 5.3 s'appliquant au format
n : parami sera
interprété comme un pointeur vers un long int.
- L
- s'appliquant aux formats e, E, f,
g ou G : parami sera interprété comme un
long double.
Si un h, l ou L s'applique à un autre format que ceux
indiqués ci-dessus, le comportement est indéterminé.
- 5
- un caractère qui peut prendre les valeurs
suivantes :
- d, i
- parami sera interprété comme un
int, et écrit sous forme décimale signée.
- u
- parami sera interprété comme un
unsigned int, et écrit sous forme décimale non signée.
- o
- parami sera interprété comme un
int, et écrit sous forme octale non signée.
- x, X
- parami sera interprété comme un
int, et écrit sous forme hexadécimale non signée.
La notation hexadécimale utilisera les lettres abcdef dans le cas du
format x, et les lettres ABCDEF dans le cas du format X.
Dans les cas qui précèdent, la précision indique le nombre minimum de
chiffres avec lesquels écrire parami.
Si parami s'écrit avec moins de chiffres, il sera complété
avec des zéros.
La précision par défaut est 1. Une valeur nulle demandée avec une précision
nulle, ne sera pas imprimée.
- c
- parami sera interprété comme un unsigned
char.
- s
- parami sera interprété comme l'adresse
d'un tableau de caractères (terminé ou non par un null).
Les caractères du tableau seront imprimés jusqu'au premier des deux évènements
possibles :
- -
- impression de précision caractères de parami.
- -
- rencontre de null dans parami.
Dans le cas où parami n'est pas terminé par un null, le
format d'impression doit comporter une indication de précision.
- p
- parami sera interprété comme un pointeur vers
void. Le pointeur sera imprimé sous une forme dépendante de
l'implémentation.
- n
- parami sera interprété comme un pointeur vers
un int auquel sera affecté le nombre de caractères écrits jusqu'alors
par cette invocation de fprintf.
- e,E
- parami sera interprété comme un
double et écrit sous la forme :
-option pe .
pf e
signe exposant
dans laquelle pe et pf sont respectivement partie entière
et partie fractionnaire de la mantisse.
La partie entière est exprimée avec un seul chiffre, la partie fractionnaire
est exprimée avec un nombre de chiffres égal à la précision.
La précision est prise égale à 6 par défaut.
Si la précision est 0, le point décimal n'apparaît pas.
L'exposant contient toujours au moins deux chiffres.
Si parami est nul, l'exposant sera nul.
Dans le cas du format E, la lettre E est imprimée à la place
de e.
- f
- parami sera interprété comme un double
et écrit sous la forme :
-option pe .
pf
dans laquelle pe et pf sont respectivement partie entière
et partie fractionnaire de la mantisse.
La partie fractionnaire est exprimée avec un nombre de chiffres égal
à la précision.
La précision est prise égale à 6 par défaut.
Si la précision est 0, le point décimal n'apparaît pas.
- g,G
- parami sera interprété comme un
double et écrit sous le format f, ou le format e, selon
sa valeur.
Si parami a un exposant inférieur à -4 ou plus grand ou égal à la
précision, il sera imprimé sous le format e, sinon il sera imprimé
sous le format f.
D'éventuels zéros à la fin de la partie fractionnaire sont enlevés.
Le point décimal n'apparaît que si il est suivi d'au moins un chiffre.
Dans ce qui précède, l'utilisation du format G implique l'utilisation
du format E à la place du format e.
- %
- Un caractère % est écrit.
Nous avons déjà vu
printf, mais nous allons la définir ici formellement.
La fonction
printf admet un nombre variable de paramètres.
Son utilisation est la suivante :
printf ( format , param1 , param2 , ... , paramn )
Un appel
printf(fmt, ...) est rigoureusement identique à
fprintf(stdout,fmt,...).
La fonction
sprintf admet un nombre variable de paramètres.
Son utilisation est la suivante :
sprintf ( chaîne , format , param1 , param2 , ... , paramn )
La fonction
sprintf réalise le même traitement que la fonction
fprintf, avec la différence que les caractères émis par
sprintf
ne sont pas écrits dans un fichier, mais dans le tableau de caractères
chaîne. Un
null est écrit dans
chaîne en fin de traitement.
source C resultat
printf("|%d|\n",1234); |1234|
printf("|%d|\n",-1234); |-1234|
printf("|%+d|\n",1234); |+1234|
printf("|%+d|\n",-1234); |-1234|
printf("|% d|\n",1234); | 1234|
printf("|% d|\n",-1234); |-1234|
printf("|%x|\n",0x56ab); |56ab|
printf("|%X|\n",0x56ab); |56AB|
printf("|%#x|\n",0x56ab); |0x56ab|
printf("|%#X|\n",0x56ab); |0X56AB|
printf("|%o|\n",1234); |2322|
printf("|%#o|\n",1234); |02322|
printf("|%10d|\n",1234); | 1234|
printf("|%10.6d|\n",1234); | 001234|
printf("|%.6d|\n",1234); |001234|
printf("|%*.6d|\n",10,1234); | 001234|
printf("|%*.*d|\n",10,6,1234); | 001234|
printf("|%f|\n",1.234567890123456789e5); |123456.789012|
printf("|%.4f|\n",1.234567890123456789e5); |123456.7890|
printf("|%.20f|\n",1.234567890123456789e5); |123456.78901234567456413060|
printf("|%20.4f|\n",1.234567890123456789e5); | 123456.7890|
printf("|%e|\n",1.234567890123456789e5); |1.234568e+05|
printf("|%.4e|\n",1.234567890123456789e5); |1.2346e+05|
printf("|%.20e|\n",1.234567890123456789e5); |1.23456789012345674564e+05|
printf("|%20.4e|\n",1.234567890123456789e5); | 1.2346e+05|
printf("|%.4g|\n",1.234567890123456789e-5); |1.235e-05|
printf("|%.4g|\n",1.234567890123456789e5); |1.235e+05|
printf("|%.4g|\n",1.234567890123456789e-3); |0.001235|
printf("|%.8g|\n",1.234567890123456789e5); |123456.79|
La fonction fscanf admet un nombre variable de paramètres.
Son utilisation est la suivante :
fscanf ( flot-de-données , format , param1 , param2 , ... , paramn )
- -
- flot-de-données est de type pointeur vers FILE.
Il pointe vers le fichier à partir duquel se fait la lecture.
- -
- format est une chaîne de caractères qui spécifie la forme
de l'entrée admissible dans flot-de-données.
- -
- les parami sont des pointeurs. Ils pointent des
variables dans lesquelles fscanf dépose les valeurs
lues dans flot-de-données, après les avoir converties en binaire.
Valeur rendue
Si au moins un
parami s'est vu affecter une valeur,
fscanf
retourne le nombre de
parami affectés.
Si il y a eu rencontre de fin de fichier ou erreur d'entrée-sortie
avant toute affectation à un
parami,
fscanf retourne
EOF.
fscanf lit une suite de caractères du fichier défini par
flot-de-données
en vérifiant que cette suite est conforme à la description qui en est faite
dans
format.
Cette vérification s'accompagne d'un effet de bord qui consiste à
affecter des valeurs aux variables pointées par les différents
parami.
- flot d'entrée
- il s'agit de la suite de caractères lus du fichier
défini par flot-de-données.
- caractères blancs
- il s'agit des six caractères suivants : espace,
tab, line feed, new line, vertical tab et
form feed.
- modèle
- un modèle est la description d'un ensemble de chaînes de
caractères. Exemple :
%d
est le modèle des chaînes formées
de chiffres décimaux, éventuellement signées.
- conforme
- on dira qu'une chaîne est conforme à un modèle quand elle
appartient à l'ensemble des chaînes décrites par le modèle. Exemple :
123
est conforme au modèle %d
.
- directive
- une directive peut être :
- -
- une suite de caractères blancs qui est un modèle d'un nombre
quelconque de caractères blancs. Exemple : un espace est un modèle pour un
nombre quelconque d'espaces, ou d'un nombre quelconque d'espace et de tab
mélangés, ou d'un nombre quelconque d'espaces, de tab et de
line-feed mélangés etc.
- -
- une suite de caractères ordinaires (c'est à dire qui ne sont ni des
caractères blancs, ni le caractère
%
) qui est un modèle pour elle-même.
Exemple : la chaîne hello
est un modèle de la seule chaîne hello
.
- -
- des séquences d'échappement introduites par le caractère
%
.
Ces séquences jouent un double rôle : elle sont à la fois un modèle
des chaînes acceptables dans le flot d'entrée, et elles sont également des
ordres de conversion de la chaîne lue et d'affectation du résultat à
une variable pointée par le parami correspondant.
Exemple : la directive %d
est un modèle des nombres
décimaux et un ordre de conversion de la chaîne lue en valeur binaire et
d'affectation à l'entier pointé par le parami correspondant.
Les séquences d'échappement se composent des éléments suivants :
- 1
- le caractère
*
(optionnel) qui indique que la
directive doit être considérée comme un pur modèle : pas de conversion de la
chaîne lue, et pas d'affectation à un parami.
- 2
- un nombre (optionnel) qui indique la longueur maximum
de la chaîne acceptable du flot d'entrée.
- 3
- un caractère optionnel, qui est un modificateur de
type, pouvant prendre l'une des valeurs suivantes :
- h
- s'appliquant aux formats d, i, n :
parami sera interprété comme un pointeur vers un short int.
- h
- s'appliquant aux formats o, u, x :
parami sera interprété comme un pointeur vers un
unsigned short int.
- l
- s'appliquant aux formats d, i, n :
parami sera interprété comme un pointeur vers un long int.
- l
- s'appliquant aux formats o, u, x :
parami sera interprété comme un pointeur vers un
unsigned long int.
- l
- s'appliquant aux formats e, f, g :
parami sera interprété comme un pointeur vers un double.
- L
- s'appliquant aux formats e, f, g :
parami sera interprété comme un pointeur vers un
long double.
- 4
- un caractère de conversion qui peut prendre l'une
des valeurs suivantes :
- d
- modèle pour un nombre décimal éventuellement précédé
d'un signe. Le parami correspondant est interprété comme un pointeur
vers un int, sauf si la directive contient un modificateur de type.
- i
- modèle pour un nombre éventuellement précédé d'un signe,
et ayant l'une des trois formes suivantes :
- -
- un nombre décimal.
- -
- un nombre débutant par
0
qui sera pris comme nombre octal.
- -
- un nombre débutant par
0x
ou 0X
, qui sera pris comme
nombre hexadécimal.
Le parami correspondant est interprété comme un pointeur
vers un int, sauf si la directive contient un modificateur de type.
- o
- modèle pour un nombre octal éventuellement précédé d'un
signe.
Le parami correspondant est interprété comme un pointeur
vers un unsigned int, sauf si la directive contient un modificateur de
type.
- u
- modèle pour un nombre décimal éventuellement précédé
d'un signe.5.4
Le parami correspondant est interprété comme un pointeur
vers un unsigned int, sauf si la directive contient un modificateur de
type.
- x
- modèle pour un nombre hexadécimal éventuellement précédé
d'un signe.
Le parami correspondant est interprété comme un pointeur
vers un unsigned int, sauf si la directive contient un modificateur de
type.
Remarque
En ce qui concerne les formats o, u, et x, le lecteur a
sans doute été surpris de voir que le parami correspondant est
interprété comme un pointeur vers un unsigned int alors que la chaîne
dans le flot d'entrée qui correspond à ces formats est un nombre
éventuellement précédé d'un signe.
Il n'y a pas d'erreur, c'est bien ce que dit la norme.
- c
- modèle pour une suite de caractères dont le nombre est
donné par le nombre (optionnel) qui indique la longueur maximum
de la chaîne acceptable du flot d'entrée (Cf plus haut).
Si ce nombre optionnel ne figure pas dans la directive, il est pris égal à 1.
Le parami correspondant est interprété comme étant un pointeur
vers un tableau de caractères suffisamment grand pour contenir la chaîne lue.
Il n'y a pas de null rajouté à la fin de la chaîne lue dans le flot
d'entrée.
- s
- modèle pour une suite de caractères non blancs.
Le parami correspondant est interprété comme un pointeur vers
un tableau de caractères suffisamment grand pour contenir la chaîne lue
plus un null terminal.
- e,f,g
- modèle pour un flottant écrit selon la syntaxe d'une
constante flottante du langage C.
Le parami correspondant est interprété comme un pointeur
vers un float , sauf si la directive contient un modificateur de
type.
- [
- Dans la chaîne format, ce caractère introduit
une séquence particulière destinée à définir un scanset.
La séquence est formée du caractère [, suivi d'une suite de
caractères quelconques, suivi du caractère ].
Si le premier caractère après le crochet ouvrant n'est pas le
caractère
^
,
le scanset est l'ensemble des caractères entre crochets.
Si le caractère après le crochet ouvrant est le caractère ^
,
le scanset est l'ensemble des caractères ne se trouvant pas
dans la chaîne entre crochets.
Le scanset peut comprendre le caractère ]
à condition de le
mettre en début soit [] ...]
ou [^]...]
selon que l'on utilise
la forme sans ou avec ^
.
Le scanset peut contenir ^
à condition de ne pas le mettre
en tête : [...^...]
.
Une directive [
est un modèle pour une suite de caractères appartenant
au scanset.
Le parami correspondant est interprété comme un pointeur vers
un tableau de caractères suffisamment grand pour contenir la chaîne lue
plus un null terminal.
- p
- modèle pour un pointeur écrit d'une manière dépendant de
l'implémentation, mais identique à l'impression par
printf
d'un
pointeur selon le format %p
.
Le parami correspondant est interprété comme un pointeur vers
un pointeur vers void.
- n
- cette directive n'est pas un modèle. Elle ne sert
qu'à mettre une valeur dans l'objet pointé par le parami
correspondant.
Le parami correspondant est interprété comme un pointeur vers un
int dans lequel
fscanf
écrit le nombre de caractères lus
jusqu'à ce moment, dans le flot de données, par cette invocation de
fscanf
.
L'exécution d'une directive %n
n'augmente pas le nombre des
parami affectés qui sera retourné par fscanf (Cf 5.5.5).
- %
- est un modèle pour le caractère
%
.
La directive complète est %%
.
La chaîne
format doit se composer d'un ensemble de directives.
Il doit y avoir autant de
parami que de directives demandant
l'affectation d'une valeur.
Si il n'y a pas suffisamment de
parami pour le
format, le
comportement n'est pas défini.
Si il y a davantage de
parami que demandé par le
format,
les
parami en excès sont évalués mais ils sont inutilisés.
La fonction fscanf
exécute dans l'ordre chaque directive du format.
Si une directive échoue, la fonction fscanf
retourne à l'appelant.
- -
- L'exécution d'une directive formée de caractères blancs, consiste à consommer
dans le flot d'entrée la plus longue séquence possible de caractères blancs.
Même si cette séquence est de taille nulle, la directive a réussi.
- -
- L'exécution d'une directive formée de caractères ordinaires, consiste à
consommer dans le flot d'entrée une séquence identique à la directive.
Au premier caractère différent, la directive a échoué et ce caractère reste non
lu.
- -
- L'exécution d'une directive formée d'une séquence d'échappement, consiste à :
- 1.
- consommer dans le flot d'entrée la plus longue séquence possible
de caractères blancs.
Cette séquence peut être de taille nulle.
Cette action ne s'applique pas aux formats c, n, ni [.
- 2.
- consommer dans le flot d'entrée la plus longue séquence possible
de caractères qui soit conforme au modèle.
Si cette séquence est de taille nulle, la directive a échoué.
- 3.
- si la directive ne contient pas le caractère
*
, convertir la
chaîne lue et l'affecter à l'objet pointé par le parami
correspondant.
Si cet objet n'est pas de la taille ou du type convenable pour la recevoir,
le comportement n'est pas défini.
La gestion des espaces blancs est assez pénible.
Il y a deux méthodes de consommation des espaces blancs du flot de données :
- 1.
- le format contient une directive formée de caractères blancs.
Si une telle directive ne peut consommer aucun caractère blanc, c'est un
cas d'échec de la directive.
- 2.
- le format contient une séquence d'échappement (autre que c, n,
ou [) dont l'exécution commence par consommer d'éventuels caractères
blancs dans le flot de données.
Si il n'y a pas de caractères blancs à consommer, ce n'est pas une condition
d'échec de la directive.
Voyons quelques conséquences.
Si le flot de données contient 23 45 on pourra les lire indifféremment
soit :
- -
- par le format "%d %d" : la première directive %d consomme
23, la directive blanc (entre les deux %d) consomme les
blancs entre 2 et 45, et la seconde directive %d
essaye de consommer des blancs, échoue (mais ce n'est pas une erreur),
puis consomme 45.
- -
- par le format "%d%d" : la première directive %d consomme
23, la seconde directive %d essaye de consommer des blancs,
réussit, puis consomme 45.
Dans les deux cas, les valeurs affectées seront bien les mêmes : 23 et 45.
Un tel phénomène ne se manifeste pas avec les séquences d'échappement dont
l'exécution ne commence pas par consommer les espaces blancs.
Par exemple, si le flot de données contient 23 jean dupond
, on
n'obtiendra pas le même résultat selon que l'on utilise le format
"%d %[ abcdefghijklmnopqrstuvwxyz]" ou le format
"%d%[ abcdefghijklmnopqrstuvwxyz]" (sans blanc après %d).
Le fscanf réussira dans les deux cas, mais dans le premier cas,
la chaîne affectée au parami sera "jean dupond" et dans
le second cas, ce sera " jean dupond"
.
Nous avons déjà vu
scanf, nous allons la définir ici formellement.
La fonction scanf admet un nombre variable de paramètres.
Son utilisation est la suivante :
scanf ( format , param1 , param2 , ... , paramn )
Un appel
scanf(fmt,...) est rigoureusement identique à
fscanf(stdin,fmt,...).
La fonction sscanf admet un nombre variable de paramètres.
Son utilisation est la suivante :
sscanf ( chaîne , format , param1 , param2 , ... , paramn )
La fonction
sscanf réalise le même traitement que la fonction
fscanf, avec la différence que les caractères lus par
sscanf
ne sont pas lus depuis un fichier, mais du tableau de caractères
chaîne. La rencontre du
null terminal de
chaîne pour
sscanf est équivalent à la rencontre de fin de fichier pour
fscanf.
Next: Récréation
Up: Les entrées-sorties
Previous: Lecture et écriture par
Bernard Cassagne
1998-12-09