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 dews=cin.get()
, le premier caractère de votre chaîne sera dans la variablews
, au lieu de simplement effacer'\n'
.
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.