2017-09-17 3 views
-3

J'essaye d'écrire un programme qui lit un tas de chaînes de l'utilisateur, puis une nouvelle ligne, et pousse toutes les chaînes que j'ai lues sur une pile. Voici ce que j'ai jusqu'à présent:Pourquoi ce code ne lit-il pas correctement les chaînes avant de rencontrer un saut de ligne?

stack<string> st; 
string str; 
while(str != "\n") 
{ 
    cin >> str; 
    st.push(str); 
} 

Cependant, cela va dans une boucle infinie et ne s'arrête pas quand je lis une nouvelle ligne. Pourquoi cela arrive-t-il? Comment je le répare?

Répondre

1

Par défaut, l'opérateur d'extraction de flux (l'opérateur >>) appliqué aux chaînes va ignorer tous les espaces. Si vous tapez A B C, puis une nouvelle ligne, puis D E F, puis essayez de lire les chaînes une à la fois en utilisant l'opérateur d'extraction de flux, vous obtiendrez les chaînes "A", "B", "C", "D", " E ", et" F "sans espace et sans saut de ligne.

Si vous voulez lire un tas de cordes jusqu'à ce que vous frappez une nouvelle ligne, vous pouvez envisager d'utiliser std::getline pour lire une ligne de texte, puis utilisez un std::istringstream pour tokenizer il:

#include <sstream> 

/* Read a full line from the user. */ 
std::string line; 
if (!getline(std::cin, line)) { 
    // Handle an error 
} 

/* Tokenize it. */ 
std::istringstream tokenizer(line); 
for (std::string token; tokenizer >> token;) { 
    // Do something with the string token 
} 

Comme une note - dans votre code d'origine, vous avez une boucle qui ressemble généralement à ceci:

string toRead; 
while (allIsGoodFor(toRead)) { 
    cin >> toRead; 
    // do something with toRead; 
} 

cette approche, en général, ne fonctionne pas parce qu'il continuera dans la boucle une fois de trop. Plus précisément, une fois que vous avez lu une entrée qui provoque la condition à false, la boucle continuera à traiter ce que vous avez lu jusqu'à présent. Il est sans doute une meilleure idée de faire quelque chose comme ceci:

while (cin >> toRead && allIsGoodFor(toRead)) { 
    do something with toRead; 
} 
+0

Downvoter: Ma logique incorrecte ici? Y a-t-il quelque chose que je peux faire pour améliorer cette réponse? – templatetypedef

+0

Ce n'est pas comme ça que vous écrivez des boucles d'entrée. –

+0

J'aime cette année (donc j'ai donné +1), mais s'il vous plaît nettoyer «certaines conditions ne sont pas vraies à propos de lire». – Charles

-2

Essayez de faire

stack<string> st; 
string str; 
while(str!="\n") 
{ 
cin>>str; 
if(str == "\n") 
{ 
break; 
} 
st.push(str); 
} 

Et voir si cela fonctionne. Et sinon, essayez

while ((str = cin.get()) != '\n') 

au lieu de

while(str!="\n") 
+2

Je ne pense pas que cela fonctionnera correctement - 'cin' saute par-dessus les espaces et donc vous ne liriez jamais un saut de ligne. – templatetypedef

+0

@templatetypedef est correct. – Charles