11
votes

std :: getline ne fonctionne pas à l'intérieur d'une boucle

J'essaie de collecter l'entrée de l'utilisateur dans une variable de chaîne qui accepte les espaces blanchisseurs pour une durée spécifiée.

Depuis l'habituel CIN >> STR n'accepte pas les espaces. "D aller avec std :: getline de

voici mon code: xxx

aucune idée?


4 commentaires

Très rarement fait les choses échouent sans aucune raison.


Essayez ce qui suit avant la boucle: STD :: COUT << "N:" << N << STD :: endl;


Oui. n a été lu correctement. J'ai entré 2 pour le N, et il imprime "N: 2"


Je pense avoir résolu votre problème. Mais concernant votre débogage, vous avez fait d'autres valeurs que 2, non? La boucle est entrée, elle "saute" la première entrée.


12 Réponses :


2
votes

Vous frappez-vous? Si vous n'êtes pas de la ligne ne retournera rien, car il attend de la fin de la ligne ...


0 commentaires

1
votes
  • est N correctement initialisé à partir d'une entrée?
  • Vous ne semblez rien faire avec GetLine. Est-ce ce que tu veux?
  • GetLine retourne une référence Istream. Fait le fait que vous laissez tomber sur le sol?

1 commentaires

Oui. J'ai essayé de l'imprimer, et n est initialisé correctement. --- J'ai coupé les codes après la gaine.



2
votes

Je suppose que vous ne lisez pas correctement n , donc il convient à zéro. Depuis 0 n'est pas moins que 0, la boucle ne s'exécute jamais.

J'ajouterais un peu d'instrumentation: xxx


1 commentaires

Non, la boucle exécute. J'utilise VC ++ 2008, je serais donc en mesure de déboguer en traçant la ligne de code par ligne.



1
votes

sur quel compilateur avez-vous essayé cela? J'ai essayé sur VC2008 et j'ai travaillé bien. 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 travaillées dans les deux compilateurs. Je n'ai pas le dernier compilateur g ++ dans mon environnement.

int n;
cin >> n;
string 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;
}


0 commentaires

18
votes

Vous pouvez voir pourquoi cela échoue si vous donnez ce que vous avez enregistré dans local (qui est un nom de variable médiocre, à la manière suivante: p): xxx

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

Ceci est parce que getline vous donne la ligne vide laissée de l'entrée de votre numéro. (Il lit le nombre, mais apparemment ne supprime pas le \ n , donc vous êtes laissé avec une ligne vierge.) Vous devez vous débarrasser d'un autre blanc restant: < pré> xxx

ceci fonctionne comme prévu.

Off thème, peut-être que ce n'était que pour l'extrait à la main, mais le code a tendance à être plus lisible Si vous n'avez pas à l'aide de NAMESPACE STD; . Il défait le but des espaces de noms. Je soupçonne que ce n'était que pour la publication ici, cependant.


2 commentaires

J'ai tendance à utiliser explicitement le préfixe STD :: Nomspace Prefix moi-même, mais il n'y a rien de mal à utiliser une déclaration dans un fichier CPP (non h).


Peut-être dans un exemple aussi simple. Il y a beaucoup de choses dans l'espace de noms std , cependant. Le niveau de fonction est le plus global que je vais utiliser avec en utilisant des directives .



1
votes

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 entrez dans le débogueur, avez-vous compilé avec optimisation (qui est autorisée à réorganiser des 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 peuplée, mais elle n'est pas traitée correctement. Par exemple, si vous souhaitez transmettre l'entrée sur les fonctions d'Old C (par exemple, ATOI () ), vous devrez extraire la chaîne de style C ( local.c_str () ).


0 commentaires

6
votes

Déclarez un caractère à INTENEZ DANS LE CHARIÈRE Return après avoir tapé le numéro. Char WS; INT N; CIN >> N; WS = CIN.GET (); / code> Cela résoudra le problème.

Utilisation CIN >> WS au lieu de ws = cin.get () , fera un premier caractère de votre chaîne pour être dans la variable ws , au lieu de simplement effacer '\ n' .


0 commentaires

0
votes

Vous pouvez utiliser directement la fonction GetLine dans la chaîne à l'aide de Délimiter comme suit:

#include <iostream>
using namespace std;
int main()
{
    string str;
    getline(cin,str,'#');
    getline(cin,str,'#');
}


1 commentaires

même peut être inséré en boucle.



3
votes

C'est assez simple. U JST besoin de mettre un cin.get () à la fin de la boucle.


1 commentaires

ça marche pour, merci



-1
votes

Il suffit d'utiliser cin.sync () avant la boucle.


1 commentaires

Il suffit de distribuer le correctif ne vous aide pas. Veuillez expliquer votre réponse également pour que cela soit bénéfique pour l'OP et les autres dans la communauté. La "raison" derrière est plus importante que la "solution".



0
votes

avant getline (CIN, local) , il suffit d'ajouter si (i == 0) {cin.ignore (); } . Cela supprimera le dernier caractère ( \ n ) de la chaîne, ce qui cause ce problème et sa nécessité uniquement pour la première boucle. Sinon, il supprimera le dernier caractère de la chaîne de chaque itération. Par exemple, xxx

et ainsi de suite.


0 commentaires

-2
votes

Il suffit d'ajouter cin.ignore () avant de getline et il fera le travail

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        string local;
        cin.ignore();
        getline(cin, local);
    }

    return 0;
}


1 commentaires

Comment cela offre-t-il une amélioration de la réponse postée il y a deux mois par Pranav Rani? En outre, ils offrent une explication et Leur réponse fonctionne.