2009-11-16 4 views
17

Y at-il une raison pour laquelle si dans mon programme, je demande à l'utilisateur pour l'entrée, et je fais:Besoin d'aide avec getline()

int number; 
string str; 
int accountNumber; 

cout << "Enter number:"; 
cin >> number; 
cout << "Enter name:"; 
getline(cin, str); 
cout << "Enter account number:"; 
cin >> accountNumber; 

Pourquoi après avoir entré le premier numéro, il affiche « Entrez le nom » , suivi immédiatement de "Entrez le numéro de compte" avant même que j'aie entré mon "str" ​​pour la ligne getline (cin, str)? Merci!

+0

double possible de [Que suis-je pas comprendre au sujet GetLine + chaînes?] (Http://stackoverflow.com/questions/8248239/what-am-i-not-understanding-about-getlinestrings) –

+0

possible duplicata de [Pourquoi std :: getline() saute l'entrée après une extraction formatée?] (http://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) –

Répondre

3
cin >> number // eat the numeric characters 
getline(cin, str) // eat the remaining newline 
2
cin >> number 

saisit uniquement les chiffres de la mémoire tampon, il quitte la « entrée » dans la mémoire tampon, qui est alors immédiatement saisi par le getline et interprété comme une chaîne vide (ou une chaîne avec seulement la nouvelle ligne, j'oublie).

+1

cin >> numéro, non? – pmr

+0

Oui, il a tapé mal c'est tout. – Secko

+0

@Secko Oui, et c'est exactement ce que je voulais communiquer. Je suis désolé si j'avais l'air d'être impoli. – pmr

12

Essayez

cout << "Enter name:"; 
cin.ignore(); 
getline(cin, str); 
1

Je pense que le problème est que cin >> passe sur le retour à la ligne (\n). Le getline() suppose que le caractère de nouvelle ligne est un espace et le transmet. Quelqu'un a posté une solution que vous pouvez utiliser.

Vous pouvez utiliser un getline(cin, dummy); factice ou la vraie chose cin.ignore(100,'\n');

16

Le getline(cin, str); lit le saut de ligne qui vient après le nombre lu précédemment, et revient tout de suite avec cette « ligne ». Pour éviter cela, vous pouvez sauter des espaces avec std::ws avant de lire le nom:

cout << "Enter number:"; 
cin >> number; 
cout << "Enter name:"; 
ws(cin); 
getline(cin, str); 
... 

Notez que ce permet aussi d'éviter les espaces au après la nouvelle ligne, donc str ne démarre pas avec des espaces, même si l'utilisateur les a fait entrée. Mais dans ce cas, c'est probablement une fonctionnalité, pas un bug ...

+0

Notez que cette méthode ne permettra pas à l'utilisateur d'entrer une ligne vide. – interjay

4

Il semble que vous vouliez une lecture basée sur les lignes. Pour cela, vous voulez probablement utiliser getline de manière cohérente, puis analyser chaque ligne si vous avez besoin d'analyser un nombre à partir de la ligne de lecture. Cela rend la lecture d'entrée plus cohérente. De cette façon, il n'est pas nécessaire de scanner manuellement la fin de chaque ligne pour garantir que l'opération de lecture suivante commence sur une nouvelle ligne.

Il facilite également l'ajout de la gestion des erreurs pour la répétition des demandes d'entrée.

par exemple.

#include <string> 
#include <iostream> 
#include <istream> 
#include <ostream> 
#include <sstream> 

int parse_integer(const std::string& input) 
{ 
    std::istringstream iss(input); 
    int result; 
    if (!(iss >> result)) 
    { 
     // error - throw something? 
    } 
    return result; 
} 

int main() 
{ 
    int number; 
    std::string str; 
    int accountNumber; 

    std::string inputline; 

    std::cout << "Enter number: "; 

    if (!std::getline(std::cin, inputline)) 
    { 
     // error - throw something? 
    } 

    number = parse_integer(inputline); 

    std::cout << "Enter name:"; 

    if (!std::getline(std::cin, inputline)) 
    { 
     // error - throw something? 
    } 

    str = inputline; 

    std::cout << "Enter account number:"; 

    if (!std::getline(std::cin, inputline)) 
    { 
     // error - throw something? 
    } 

    accountNumber = parse_integer(inputline); 

    return 0; 
}