std :: getline ne fonctionne pas dans une boucle for

J’essaie de collecter les entrées de l’utilisateur dans une variable chaîne qui accepte les espaces blancs pendant un laps de temps spécifié.

Puisque le cin >> str habituel n’accepte pas les espaces, nous utiliserions donc std :: getline à partir de

Voici mon code:

 #include  #include  #include  #include  using namespace std; int main() { int n; cin >> n; for(int i = 0; i < n; i++) { string local; getline(cin, local); // This simply does not work. Just skipped without a reason. //............................ } //............................ return 0; } 

Une idée?

Vous pouvez voir pourquoi cela échoue si vous affichez ce que vous avez stocké dans local (qui est un nom de variable médiocre, au fait: P):

 #include  #include  #include  #include  using namespace std; int main() { int n; cin >> n; for(int i = 0; i < n; i++) { string local; getline(cin, local); std::cout << "> " << local << std::endl; } //............................ return 0; } 

Vous verrez qu'il imprime une nouvelle ligne après > immédiatement après avoir entré votre numéro. Il passe ensuite à la saisie du rest.

En effet, getline vous donne la ligne vide laissée par la saisie de votre numéro. (Il lit le numéro, mais apparemment, ne supprime pas le \n , il ne rest donc qu'une ligne vierge.) Vous devez d'abord vous débarrasser de tout espace vide:

 #include  #include  #include  #include  using namespace std; int main() { int n; cin >> n; cin >> ws; // stream out any whitespace for(int i = 0; i < n; i++) { string local; getline(cin, local); std::cout << "> " << local << std::endl; } //............................ return 0; } 

Cela fonctionne comme prévu.

Hors sujet, c'était peut-être uniquement pour l'extrait de code sous la main, mais le code a tendance à être plus lisible si vous n'avez pas using namespace std; . Il défait le but des espaces de noms. Je soupçonne que c'était uniquement pour poster ici.

Frappez-vous entrer? Sinon, get line ne retournera rien, car il attend la fin de la ligne …

J’imagine que vous ne lisez pas n correctement, la conversion est donc nulle. Puisque 0 n’est pas inférieur à 0, la boucle ne s’exécute jamais.

J’appendais un peu d’instrumentation:

 int n; cin >> n; std::cerr << "n was read as: " << n << "\n"; // <- added instrumentation for // ... 

Déclarez un caractère à insérer dans le retour chariot après avoir saisi le numéro. char ws;int n;cin>>n;ws=cin.get(); Cela résoudra le problème.

En utilisant cin>>ws au lieu de ws=cin.get() , le premier caractère de votre chaîne sera dans la variable ws , au lieu de simplement effacer '\n' .

  • Est-ce que n est correctement initialisé à partir de l’entrée?
  • Vous semblez ne rien faire avec getline. c’est ce que tu veux?
  • getline renvoie une référence istream. Est-ce que le fait de le laisser tomber sur le sol a de l’importance?

Sur quel compilateur avez-vous essayé cela? J’ai essayé sur VC2008 et a bien fonctionné. Si j’ai compilé le même code sur g ++ (GCC) 3.4.2. Cela n’a pas fonctionné correctement. Vous trouverez ci-dessous les versions utilisées dans les deux compilateurs. Je n’ai pas le dernier compilateur g ++ dans mon environnement.

 int n; cin >> n; ssortingng local; getline(cin, local); // don't need this on VC2008. But need it on g++ 3.4.2. for (int i = 0; i < n; i++) { getline(cin, local); cout << local; } 

La question importante est “que faites-vous avec la chaîne qui vous donne l’idée que l’entrée a été ignorée?” Ou, plus précisément, “pourquoi pensez-vous que l’entrée a été ignorée?”

Si vous parcourez le débogueur, avez-vous compilé avec l’optimisation (qui permet de réorganiser les instructions)? Je ne pense pas que ce soit votre problème, mais c’est une possibilité.

Je pense qu’il est plus probable que la chaîne soit remplie mais elle n’est pas gérée correctement. Par exemple, si vous souhaitez passer l’entrée aux anciennes fonctions C (par exemple, atoi() ), vous devez extraire la chaîne de style C ( local.c_str() ).

Vous pouvez directement utiliser la fonction getline dans une chaîne en utilisant le délimiteur comme suit:

 #include  using namespace std; int main() { ssortingng str; getline(cin,str,'#'); getline(cin,str,'#'); } 

vous pouvez entrer str autant de fois que vous le souhaitez, mais une condition est la suivante: vous devez passer le “#” (3ème argument) en tant que délimiteur, c’est-à-dire que la chaîne accepte les entrées jusqu’à ce que “#” ait été actionné, quel que soit le caractère de nouvelle ligne.