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";

}
36
demandé sur msrd0 2014-08-24 23:17:26

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.)

30
répondu savageWays 2016-01-30 22:53:37

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.

5
répondu Dan 2016-12-16 19:48:55

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.

4
répondu shafeen 2014-08-24 19:20:52

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.

1
répondu vinod 2016-02-03 14:37:15

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>.

-1
répondu Green Mahmud 2018-04-25 16:04:45