Quand et pourquoi je dois utiliser cin.ignorer () en C++?
j'ai écrit un programme très basique en C++ qui demandait à l'utilisateur d'entrer un nombre puis une chaîne. À ma grande surprise, en lançant le programme, il n'a jamais cessé de demander la corde. Il a juste sauté sur elle. Après avoir lu un peu sur StackOverflow, j'ai découvert que j'avais besoin d'ajouter une ligne qui disait:
cin.ignore(256, 'n');
avant la ligne qui obtient la chaîne d'entrée. En ajoutant cela, on a réglé le problème et fait fonctionner le programme. Ma question est pourquoi C++ a besoin de ceci cin.ignore()
ligne et comment puis-je prévoir quand j'ai besoin d'utiliser cin.ignore()
?
Voici le programme que j'ai écrit:
#include <iostream>
#include <string>
using namespace std;
int main()
{
double num;
string mystr;
cout << "Please enter a number: " << "n";
cin >> num;
cout << "Your number is: " << num << "n";
cin.ignore(256, 'n'); // Why do I need this line?
cout << "Please enter your name: n";
getline (cin, mystr);
cout << "So your name is " << mystr << "?n";
cout << "Have a nice day. n";
}
5 réponses
ignorer est exactement ce que le nom implique.
il ne" jette pas " quelque chose dont vous n'avez pas besoin à la place, il ignore le nombre de caractères que vous spécifiez quand vous l'appelez, jusqu'au char que vous spécifiez comme point de rupture.
il fonctionne avec les tampons d'entrée et de sortie.
Essentiellement, pour std::cin
instructions vous utilisez ignorer avant de faire un getline
appeler, parce que quand un utilisateur tape quelque chose avec std::cin
, ils frappent enter et a '\n'
char obtient dans le cin
tampon. Ensuite, si vous utilisez getline
, il obtient le newline char au lieu de la chaîne que vous voulez. Afin de vous faire un std::cin.ignore(1000,'\n')
et qui devrait effacer la mémoire tampon jusqu'à la chaîne que vous souhaitez. (Le 1000 est mis là pour sauter une quantité spécifique de caractères avant le point de rupture spécifié, dans ce cas, le caractère \n newline.)
vous y pensez de la mauvaise façon. Vous êtes en train de penser par étapes logiques à chaque fois cin
ou getline
est utilisé. Ex. Demandez d'abord un numéro, puis un nom. C'est la mauvaise façon de penser cin
. Donc vous courez dans une condition de course parce que vous supposez que le flux est clair chaque fois que vous demandez une entrée.
Si vous écrivez votre programme purement pour l'entrée, vous trouverez le problème:
void main(void)
{
double num;
string mystr;
cin >> num;
getline(cin, mystr);
cout << "num=" << num << ",mystr=\'" << mystr << "\'" << endl;
}
ci-dessus, vous pensez, "d'abord obtenir un numéro." Si vous tapez 123
appuyez sur entrée et votre sortie sera num=123,mystr=''
. Pourquoi est-ce? C'est parce que dans le ruisseau vous avez 123\n
et 123
est divisé en num
variable tandis que \n
est encore dans le ruisseau. Lire le doc pourgetline
fonction par défaut, il va chercher dans le istream
jusqu'à \n
est rencontré. Dans cet exemple, depuis \n
est dans le flux, on dirait qu'il "sauté", mais cela a fonctionné correctement.
pour que ce qui précède fonctionne, vous devrez entrez 123Hello World
bien sortie num=123,mystr='Hello World'
. Que, ou vous mettre un cin.ignore
entre le cin
et getline
pour qu'il se brise en étapes logiques que vous attendez.
C'est pourquoi vous avez besoin de l' ignore
la commande. Parce que vous pensez à lui dans les étapes logiques plutôt que dans une forme de ruisseau de sorte que vous courez dans une condition de course.
prenez un autre exemple de code que l'on trouve couramment dans les écoles:
void main(void)
{
int age;
string firstName;
string lastName;
cout << "First name: ";
cin >> firstName;
cout << "Last name: ";
cin >> lastName;
cout << "Age: ";
cin >> age;
cout << "Hello " << firstName << " " << lastName << "! You are " << age << " years old!" << endl;
}
ci-dessus semble être dans la logique. Tout d'abord demander le prénom, le nom, puis l'âge. Donc si vous n'avez John
enter, puis Doe
enter, puis 19
entrée, l'application fonctionne à chaque étape logique. Si vous pensez à elle en "flux", vous pouvez simplement entrer John Doe 19
sur la question "prénom:" et cela fonctionnerait aussi bien et semblerait sauter les questions restantes. Pour que ce qui précède fonctionne par étapes logiques, vous devez ignore
le flux restant pour chaque pause logique dans les questions.
n'oubliez pas de penser à votre entrée de programme car il lit à partir d'un" flux " et pas dans les étapes logiques. Chaque fois que vous appelez cin
il est lu à partir d'un flux. Cela crée une application assez buggée si l'utilisateur entre la mauvaise entrée. Par exemple, si vous avez entré un caractère où un cin >> double
est attendue, l'application produira un résultat plutôt (apparemment) bizarre.
quand vous voulez jeter un certain nombre de caractères du flux d'entrée manuellement.
un cas d'utilisation très courant est d'utiliser ceci pour ignorer en toute sécurité les caractères newline car cin laissera parfois des caractères newline que vous devrez parcourir pour accéder à la ligne suivante de saisie.
pour faire court, cela vous donne de la flexibilité quand vous manipulez les entrées de flux.
la fonction Ignore est utilisée pour sauter(jeter/rejeter) les caractères dans le flux d'entrée. Ignore file est associé au fichier istream. Considérons la fonction ci-dessous ex: cin.ignorer (120,'/n'); la fonction particulière saute le caractère d'entrée suivant de 120 ou de sauter les caractères jusqu'à ce qu'un caractère newline soit lu.
Il est préférable d'utiliser scanf(" %[^\n]",str) en c++ que cin.ignore () après Cin>> statement.Pour ce faire, vous devez d'abord inclure l'en-tête < cstdio>.