6.2.1 Mise en oeuvre de scanf

Icône de l'outil pédagogique Mise en oeuvre de scanf

La fonction scanf permet de lire les informations tapées au clavier par l'utilisateur selon un certain format. Les informations lues sont converties en caractères, entiers ou réels suivant le format attendu.

Il existe une différence fondamentale entre printf et scanf. Pour printf, c'est la valeur de la variable qui est passée en argument à la fonction. Dans le cas de scanf, cette valeur est inconnue : c'est elle qui sera lue au clavier, puis rangée dans un emplacement mémoire qui reste à spécifier. C'est donc l'adresse de cet emplacement qu'il faut fournir en argument à la fonction scanf pour qu'elle puisse y ranger la valeur lue au clavier. L’argument fourni à scanf est l’adresse de la variable où scanf doit ranger la valeur lue au clavier.

En C, l'adresse d'une variable se représente en faisant précéder le nom de la variable du symbole & :

l'adresse de la variable toto est &toto. 

La syntaxe de la fonction scanf est : 

nb_val_lues = scanf("format", arg_1, arg_2, ..., arg_n) ;
où format représente une suite de codes formats, construits comme avec printf, et arg_1, ..., arg_n sont les adresses
des variables où doivent être rangées les valeurs lues par scanf. Par exemple :

nb_val_lues = scanf("%ld", &toto); si toto est une variable long int

 

La valeur renvoyée par scanf est le nombre de valeurs que scanf a réellement réussi à lire : elle sert à protéger les saisies contre les erreurs de l'utilisateur (voir paragraphe 6.2.3 Valeur retournée par scanf).

Exemple 39 : Saisie (non protégée) par scanf
Un exemple de saisie "blindée" sera vue à l'exemple du paragraphe correspondant.

L'oubli de l'opérateur d'adresse & n'entraîne pas de message d'erreur de la part du compilateur. Mais la valeur lue sera écrite n'importe où en mémoire !

 

On peut lire plusieurs valeurs numériques dans une même instruction scanf. Les valeurs à lire doivent être séparées par un séparateur lors de la frappe au clavier : les caractères ESPACE, fin de ligne (touche ENTRÉE) ou tabulation sont des séparateurs. scanf saute tous les séparateurs avant de constituer une nouvelle valeur numérique.

Ainsi, en réponse à l'instruction 

scanf("%hd%hd", &entier1, &entier2) ;

on peut taper indifféremment 526___12(ENTRÉE) ou __526(ENTRÉE) ou (TAB)_12_. scanf sautera les espaces (représentés par _), les fins de ligne (ENTRÉE) et les tabulations (TAB) avant de lire la valeur numérique suivante.

Les codes formats successifs dans une même instruction scanf doivent se suivre sans le moindre espace (scanf("%hd%f%hd",…). Si un espace ou toute autre chaîne de caractères sépare deux codes formats, ils devront être exactement retrouvés lors de la saisie des valeurs, ce qui laisse peu de marge à l'utilisateur.

Par exemple, si l'instruction est scanf("%hd, %hd", &entier1, &entier2) (les 2 codes formats sont séparés par une virgule et un espace), l'utilisateur devra impérativement taper une virgule et un espace entre les deux entiers (par exemple : 23,_6) sous peine de provoquer une mauvaise lecture.

C’est utile pour imposer le format d’une saisie, comme celle d’une date avec le format jj/mm/aa :

scanf("%hd/%hd/%hd ", &jour, &mois, &annee) ;