J'ai le programme suivant:
int main(int argc, char *argv[])
{
int a, b;
char c1, c2;
printf("Enter something: ");
scanf("%d",&a); // line 1
printf("Enter other something: ");
scanf("%d", &b); // line 2
printf("Enter a char: ");
scanf("%c",&c1); // line 3
printf("Enter another char: ");
scanf("%c", &c2); // line 4
printf("Done"); // line 5
system("PAUSE");
return 0;
}
Comme je l'ai lu dans le livre C, l'auteur dit que scanf()
a laissé un nouveau caractère de ligne dans le tampon. Par conséquent, le programme ne s'arrête pas à la ligne 4 pour permettre à l'utilisateur de saisir les données. Il stocke plutôt le nouveau caractère de ligne dans C2 et le déplace à la ligne 5.
Est-ce correct?
Cependant, cela ne se produit-il qu'avec les types de données char
? Parce que je n'ai pas vu ce problème avec les types de données int
comme dans les lignes 1, 2, 3. Est-ce correct?
La fonction scanf()
supprime automatiquement les espaces avant d'essayer d'analyser des conversions autres que des caractères. Les formats de caractères (principalement %c
; également les ensembles d'analyse %[…]
- et %n
) sont l'exception; ils ne suppriment pas les espaces.
Utilisez " %c"
avec un blanc au début pour ignorer les espaces blancs facultatifs. N'utilisez pas de blanc de fin dans une chaîne au format scanf()
.
Notez que cela ne consomme toujours pas les blancs de fin laissés dans le flux d'entrée, pas même à la fin d'une ligne, donc faites attention si vous utilisez également getchar()
ou fgets()
sur le même flux d'entrée. Scanf ignore simplement les conversions entre espaces {before}, comme pour %d
et les conversions sans caractère.
Notez que les "directives" non-d'espaces (pour utiliser la terminologie POSIX scanf ) autres que les conversions, comme le texte littéral dans scanf("order = %d", &order);
, n'ignorent pas non plus les espaces. La valeur littérale order
doit correspondre au prochain caractère à lire.
Donc, vous voulez probablement que " order = %d"
soit présent si vous voulez ignorer une nouvelle ligne de la ligne précédente tout en exigeant une correspondance littérale sur une chaîne fixe, comme cette question .
Utilisez scanf(" %c", &c2);
. Cela résoudra votre problème.
Une autre option (que j’ai obtenue de ici ) consiste à lire et à ignorer la nouvelle ligne en utilisant l’option Affectation-Suppression. Pour cela, nous venons de mettre un format permettant de lire un caractère avec un astérisque compris entre %
et c
:
scanf("%d%*c",&a); // line 1
scanf("%c%*c",&c1); // line 3
scanf
lira alors le caractère suivant (c'est-à-dire la nouvelle ligne) mais ne l'attribuera à aucun pointeur.
En fin de compte, cependant, je seconderais la dernière option de la FAQ :
Selon vos besoins, vous pouvez également oublier scanf ()/getchar (), utiliser fgets () pour obtenir une ligne de texte de l’utilisateur et l’analyser vous-même.
Utilisez getchar()
avant d'appeler la deuxième scanf()
.
scanf("%c", &c1);
getchar(); // <== remove newline
scanf("%c", &c2);