1 of 24

/ )

( 1

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

CHAPITRE IV

2 of 24

/ )

( 2

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

      • les fonctions printf et scanf pour afficher des informations à l’écran ou pour en lire au clavier
      • On va étudier en détail les différentes possibilités de ces fonctions
        • quelles sont les écritures autorisées pour des nombres fournis en données ? Que se passe-t-il lorsque l’utilisateur ne les respecte pas ?
        • comment organiser les données lorsque l’on mélange les types numériques et les types caractères ?
        • que se produit-il lorsque, en réponse à scanf, on fournit trop ou trop peu d’informations ?
        • comment agir sur la présentation des informations à l’écran ?

3 of 24

/ )

( 3

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

1) Les possibilités de la fonction printf

      • Les principaux codes de conversion

c

(char)

caractère affiché « en clair »

(convient à short ou à int compte tenu des conversions systématiques)

d

(int)

(convient aussi à char ou à short, compte tenu des conversions systématiques)

u

(unsigned int)

(convient aussi à unsigned char ou à unsigned short, compte tenu des conversions systématiques)

ld

(long)

long

f

(double / float)

(compte tenu des conversions systématiques float -> double)

écrit en notation décimale avec six chiffres après le point

(1.234500 ou 123.456789)

e

(double / float)

(compte tenu des conversions systématiques float -> double)

écrit en notation exponentielle (mantisse entre 1 inclus et 10 exclu)

avec six chiffres après le point décimal,

(x.xxxxxxe+yyy ou x.xxxxxxe-yyy pour les nombres positifs)

(-x.xxxxxxe+yyy ou -x.xxxxxxe-yyy pour les nombres négatifs)

s

Chaîne de caractères dont on fournit l’adresse

(sera étudiée ultérieurement)

4 of 24

/ )

( 4

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

1) Les possibilités de la fonction printf

      • Action sur le gabarit d’affichage
        • Les entiers sont affichés avec le nombre de caractères nécessaires (sans espaces avant ou après)
        • Les flottants sont affichés avec six chiffres après le point (aussi bien pour e et f)
        • Un nombre placé après % dans le code de format précise un gabarit d’affichage, (nombre minimal de caractères à utiliser)

printf ("%3d", n) ; /* entier avec 3 caractères minimum */

n = 20 ^20

n = 3 ^^3

n = 2358 2358

n = -5200 -5200

printf ("%f", x) ; /* notation décimale gabarit par défaut */

/* (6 chiffres après point) */

x = 1.2345 1.234500

x = 12.3456789 12.345679

5 of 24

/ )

( 5

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

1) Les possibilités de la fonction printf

      • Action sur le gabarit d’affichage

printf ("%10f", x) ; /* notation décimale - gabarit mini 10 */

/* (toujours 6 chiffres après point) */

x = 1.2345 ^^1.234500

x = 12.345 ^12.345000

x = 1.2345E5 123450.000000

printf ("%e", x); /*notation exponentielle -gabarit par défaut*/

/* (6 chiffres après point) */

x = 1.2345 1.234500e+000

x = 123.45 1.234500e+002

x = 123.456789E8 1.234568e+010

x = -123.456789E8 -1.234568e+010

6 of 24

/ )

( 6

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

1) Les possibilités de la fonction printf

      • Actions sur la précision
        • Pour les types flottants, on peut spécifier un nombre de chiffres (inférieur à 6) après le point décimal (pour la notation décimale ou exponentielle). Ce nombre doit apparaître, précédé d’un point, avant le code de format (et après le gabarit).

printf ("%10.3f", x) ; /* notation décimale, gabarit mini 10 */

/* et 3 chiffres après point */

x = 1.2345 ^^^^^1.235

x = 1.2345E3 ^^1234.500

x = 1.2345E7 12345000.000

printf ("%12.4e", x); /*notation exponentielle, gabarit mini 12*/

/* et 4 chiffres après point */

x = 1.2345 ^1.2345e+000

x = 123.456789E8 ^1.2346e+010

7 of 24

/ )

( 7

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

1) Les possibilités de la fonction printf

      • Actions sur la précision
        • Le signe moins (-), (comme dans %-4d ou %-10.3f), demande de cadrer l’affichage à gauche au lieu de le cadrer (par défaut) à droite ; les éventuels espaces supplémentaires seront placés à droite et non plus à gauche de l’information affichée
        • Le caractère * figurant à la place d’un gabarit ou d’une précision signifie que la valeur effective est fournie dans la liste des arguments de printf

        • printf retourne le nombre de caractères qu’elle a réellement affichés (ou -1 en cas d’erreur)

printf ("%8.*f", n, x) ;

n = 1 x = 1.2345 ^^^^^1.2

n = 3 x = 1.2345 ^^^1.234

n = printf ("....", ....)

8 of 24

/ )

( 8

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

1) Les possibilités de la fonction printf

      • Cas d’erreur de programmation
        • Code de format en désaccord avec le type de l’expression
          • Lorsque le code de format, correspond à une information de même taille que celle relative au type de l’expression, les conséquences de l’erreur se limitent à une mauvaise interprétation de l’expression

Exemple, lorsque l’on écrit une valeur de type int en %u ou une valeur de type unsigned int en %d

          • Lorsque le code format correspond à une information de taille différente de celle relative au type de l’expression, les conséquences sont généralement plus désastreuses, (décalage des valeurs à affiché)
        • Nombre de codes de format différent du nombre d’expressions de la liste
          • Dans ce cas, le C cherche à satisfaire le contenu du format

Si des expressions de la liste n’ont pas de code format, elles ne seront pas affichées

printf ("%d", n, p) ; /* p ne sera pas affichée */

9 of 24

/ )

( 9

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

1) Les possibilités de la fonction printf

      • Cas d’erreur de programmation
          • Si vous prévoyez trop de codes de format, les conséquences seront là encore assez désastreuses puisque printf cherchera à afficher n’importe quoi

printf ("%d %d ", n) ; /*la valeur de la seconde est aléatoire*/

10 of 24

/ )

( 10

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

1) Les possibilités de la fonction printf

      • La macro putchar
        • L ’expression : putchar (c) joue le même rôle que : printf ("%c", c)

Son exécution est toutefois plus rapide, dans la mesure où elle ne fait pas appel au mécanisme d’analyse de format.

        • putchar n’est pas une vraie fonction mais une macro. Ses instructions (écrites en C) seront incorporées à votre programme par la directive : #include <stdio.h>

11 of 24

/ )

( 11

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Les principaux codes de conversion de scanf

c

char

d

int

u

unsigned int

hd

short int

hu

unsigned short

ld

long int

lu

unsigned long

f ou e

float : décimale (éventuellement sans point, c’est-à-dire comme un entier) ou exponentielle (avec la lettre e ou E)

lf ou le

double avec la même présentation que ci-dessus

s

chaîne de caractères dont on fournit l’adresse

12 of 24

/ )

( 12

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Notions de tampon et de séparateurs

Lorsque scanf attend que vous lui fournissiez des données, l’information frappée au clavier est rangée temporairement dans l’emplacement mémoire nommé « tampon ».

la mémoire tampon est exploré, caractère par caractère par scanf, au fur et à mesure des besoins. Il existe un pointeur qui précise quel est le prochain caractère à prendre en compte.

D’autre part, certains caractères dits « séparateurs » (ou « espaces blancs ») jouent un rôle particulier dans les données. Les deux principaux sont l’espace et la fin de ligne (\n)

13 of 24

/ )

( 13

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Premières règles utilisées par scanf

Tout les codes de format (excepté %c et %s) entraînent l’avancement du pointeur jusqu’au premier caractère différent d’un séparateur

Puis scanf prend en compte tous les caractères suivants jusqu’à la rencontre d’un séparateur (en y plaçant le pointeur)

Le code de format %c entraîne la prise en compte du caractère désigné par le pointeur (même s’il s’agit d’un séparateur comme espace ou fin de ligne), et le pointeur est simplement avancé sur le caractère suivant du tampon

        • Exemples, soit n(int) et p(int) et c(char) (^ désigne un espace et @ une fin de ligne)

scanf ("%d%d", &n, &p) ;

12^25@ n = 12 p = 25

^12^^25^^@ n = 12 p = 25

12@

@

^25@ n = 12 p = 25

14 of 24

/ )

( 14

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Premières règles utilisées par scanf

Exemples, soit n(int) et p(int) et c(char) (^ désigne un espace et @ une fin de ligne)

scanf ("%c%d", &c, &n) ;

a25@ c = 'a' n = 25

a^^25@ c = 'a' n = 25

scanf ("%d%c", &n, &c) ;

12^a@ n = 12 c = ' '

15 of 24

/ )

( 15

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Imposition d’un gabarit maximal

Dans un code de format de scanf, on peut préciser un gabarit.

Dans ce cas, le traitement d’un code de format s’interrompt soit à la rencontre d’un séparateur, soit lorsque le nombre de caractères indiqués a été atteint (attention, les séparateurs éventuellement sautés auparavant ne sont pas comptabilisés !)

        • Exemple

scanf ("%3d%3d", &n, &p)

12^25@ n = 12 p = 25

^^^^^12345@ n = 123 p = 45

12@

25@ n = 12 p = 25

16 of 24

/ )

( 16

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Rôle d’un espace dans le format

Un espace entre deux codes de format demande à scanf de faire avancer le pointeur au prochain caractère différent d’un séparateur.

C’est ce qui se passe lorsque l’on a affaire à un code de format correspondant à un type numérique.

En revanche, cela n’était pas le cas pour les caractères

        • Exemple

scanf ("%d^%c", &n, &c) ; /* ^ désigne un espace */

/* %d^%c est différent de %d%c */

12^a@ n = 12 c = 'a'

12^^^a@ n = 12 c = 'a'

12@a@ n = 12 c = 'a'

17 of 24

/ )

( 17

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Cas où un caractère invalide apparaît dans une donnée
        • Exemple

Lors du traitement du code %d, scanf rencontre les caractères 1, puis 2, puis a.

Ce caractère a ne convenant pas à la fabrication d’une valeur entière, scanf interrompt son exploration et fournit donc la valeur 12 pour n.

L ’espace qui suit %d dans le format n’a aucun effet puisque le caractère courant est le caractère a (différent d’un séparateur).

Le traitement du code %c amène scanf à prendre ce caractère courant (a) et à l’affecter à la variable c.

scanf ("%d^%c", &n, &c) ; /* ^ désigne un espace */

12a@ n = 12 c = 'a'

18 of 24

/ )

( 18

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • D’une manière générale, dans le traitement d’un code de format, scanf arrête son exploration du tampon dès que l’une des trois conditions est satisfaite :
        • Rencontre d’un caractère séparateur
        • Gabarit maximal atteint (s’il y en a un de spécifié),
        • Rencontre d’un caractère invalide, par rapport à l’usage qu’on veut en faire (par exemple un point pour un entier, une lettre autre que E ou e pour un flottant,...). Notez bien l’aspect relatif de cette notion de caractère invalide.

19 of 24

/ )

( 19

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Arrêt prématuré de scanf
        • Exemple

        • La valeur fournie par scanf est le nombre de valeurs convenablement lues
          • Dans le premier cas, la valeur est égale à 3
          • Dans le deuxième cas, le caractère b a interrompu le traitement du premier code %d, la valeurs et fournit en retour est 1. Les valeurs de p et de c restent inchangées (éventuellement indéfinies)
          • Dans le troisième cas, le même mécanisme d’arrêt prématuré se produit dès le traitement du premier code de format, et le nombre de valeurs correctement lues est 0

compte = scanf ("%d^%d^%c", &n, &p, &c) ; /* ^ désigne un espace*/

12^25^b@ n = 12 p = 25 c = 'b' compte = 3

12b@ n = 12 p inchangé c inchangé compte = 1

indéfini indéfini

b@ n inchangé p inchangé c inchangé compte = 0

indéfini indéfini indéfini

20 of 24

/ )

( 20

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Cas d’erreur
        • Erreurs de programmation
          • Code de format en désaccord avec le type de l’expression

Si le code de format correspond à un type de longueur égale à celle de la lvalue mentionnée dans la liste, les conséquences se limitent à l’introduction d’une mauvaise valeur

Si la lvalue a une taille inférieure à celle correspondant au type mentionné dans le code format, il y aura écrasement d’un emplacement mémoire

          • Nombre de codes de format différent du nombre d’éléments de la liste

scanf cherche toujours à satisfaire le contenu du format. Les conséquences sont limitées dans le cas où le format comporte moins de codes que la liste ; ainsi, dans cette instruction, on ne cherchera à lire que la valeur de n :

Dans le cas où le format comporte plus de codes que la liste, on cherchera à affecter des valeurs à des emplacements (presque) aléatoires de la mémoire.

scanf ("%d", &n, &p) ;

21 of 24

/ )

( 21

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • Cas d’erreur
        • Mauvaise réponse de l’utilisateur (Exemple: boucle infinie sur un caractère invalide)

donnez un nombre : 12

voici son carré : 144

donnez un nombre : &

voici son carré : 144

donnez un nombre : voici son carré : 144

donnez un nombre : voici son carré : 144

donnez un nombre : voici son carré : 144

donnez un nombre : voici son carré : 144

^C

main() {

int n ;

do

{ printf ("donnez un nombre : ") ;

scanf ("%d", &n) ;

printf ("voici son carré : %d\n", n*n) ;

}

while (n) ; }

22 of 24

/ )

( 22

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

2) Les possibilités de la fonction scanf

      • La macro getchar
        • L ’expression : c = getchar() joue le même rôle que : scanf ("%c", &c)

tout en étant plus rapide puisque ne faisant pas appel au mécanisme d’analyse d’un format.

        • getchar utilise le même tampon (image d’une ligne) que scanf.
        • getchar est une macro dont les instructions figurent dans stdio.h. l’omission d’une instruction #include conduit à une erreur à l’édition de liens

23 of 24

/ )

( 23

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

Exercice 1

1) Quels résultats fournit le programme suivant ?

#include <stdio.h>

main ()

{ int n = 543 ;

int p = 5 ;

float x = 34.5678;

printf ("A : %d %f\n", n, x) ;

printf ("B : %4d %10f\n", n, x) ;

printf ("C : %2d %3f\n", n, x) ;

printf ("D : %10.3f %10.3e\n", x, x) ;

printf ("E : %*d\n", p, n) ;

printf ("F : %*.*f\n", 12, 5, x) ;

}

Exercice 1 :

A : 543 34.567799

B : 543 34.567799

C : 543 34.567799

D : 34.568 3.457e+001

E : 543

F : 34.56780

24 of 24

/ )

( 24

Langage C

I. II. III. IV. V. VI. VII. VIII. IX.

Les entrées-sorties conversationnelles

Exercice 2

2) Quelles seront les valeurs lues dans les variables n et p (de type int), par l’instruction suivante ?

scanf ("%4d %2d", &n, &p) ;

lorsqu’on lui fournit les données suivantes (le symbole ^ représente un espace et le symbole @ représente une fin de ligne, c’est-à-dire une validation) ?

a) 12^45@

b) 123456@

c) 123456^7@

d) 1^458@

e) ^^^4567^^8912@