Tout d'abord, évitez scanf()
. L'utiliser ne vaut pas la peine de souffrir.
Voir : Pourquoi tout le monde dit qu'il ne faut pas utiliser scanf ? Que dois-je utiliser à la place ?
L'utilisation d'un caractère d'espacement dans scanf()
ignorerait le nombre de caractères d'espacement restant dans le flux d'entrée, mais que faire si vous avez besoin de lire plus d'entrées ? Pensez-y :
#include <stdio.h>
int main(void)
{
char ch1, ch2;
scanf("%c", &ch1); /* Leaves the newline in the input */
scanf(" %c", &ch2); /* The leading whitespace ensures it's the
previous newline is ignored */
printf("ch1: %c, ch2: %c\n", ch1, ch2);
/* All good so far */
char ch3;
scanf("%c", &ch3); /* Doesn't read input due to the same problem */
printf("ch3: %c\n", ch3);
return 0;
}
Si le troisième scanf() peut être corrigé de la même manière en utilisant un espace en tête, ce n'est pas toujours aussi simple que cela. Un autre problème majeur est, scanf()
ne rejettera aucune entrée dans le flux d'entrée si elle ne correspond pas au format. Par exemple, si vous entrez abc
pour un int
comme : scanf("%d", &int_var);
puis abc
devra être lu et jeté. Réfléchissez :
#include <stdio.h>
int main(void)
{
int i;
while(1) {
if (scanf("%d", &i) != 1) { /* Input "abc" */
printf("Invalid input. Try again\n");
} else {
break;
}
}
printf("Int read: %d\n", i);
return 0;
}
Un autre problème courant est le mélange scanf()
y fgets()
. Considérez :
#include <stdio.h>
int main(void)
{
int age;
char name[256];
printf("Input your age:");
scanf("%d", &age); /* Input 10 */
printf("Input your full name [firstname lastname]");
fgets(name, sizeof name, stdin); /* Doesn't read! */
return 0;
}
L'appel à fgets()
n'attend pas l'entrée car la nouvelle ligne laissée par l'appel scanf() précédent est lue et fgets() termine la lecture de l'entrée lorsqu'il rencontre une nouvelle ligne.
Il y a beaucoup d'autres problèmes similaires associés à scanf()
. C'est pourquoi il est généralement recommandé de l'éviter.
Alors, quelle est l'alternative ? Utiliser fgets()
de la manière suivante pour lire un seul caractère :
#include <stdio.h>
int main(void)
{
char line[256];
char ch;
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
ch = line[0];
printf("Character read: %c\n", ch);
return 0;
}
Un détail à prendre en compte lors de l'utilisation de fgets()
lira le caractère de nouvelle ligne s'il y a assez de place dans le tampon inut. Si ce n'est pas souhaitable, vous pouvez le supprimer :
char line[256];
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
line[strcpsn(line, "\n")] = 0; /* removes the trailing newline, if present */