2009-11-16 7 views
1

Pourquoi quand je suis entré dans la boucle ci-dessous et je tape quelque chose la première instruction cmdstd: getline (std :: cin, cmdInput); ne lit pas l'entrée entrée. Par exemple, si j'ai entré "b 8", il devrait afficher "cmd is b 8", mais il passe à la lecture suivante std :: getline (std :: cin, input); et affiche "c'est b" à la placeerreur C++ STD Cin dans while

while (editingMode == TRUE) { 
    std::getline(std::cin, cmdInput); 
    istringstream cmdiss(cmdInput); 
    cout << "you entered: " << cmdInput <<endl; 
    if (cmdInput != "") {  
     copy(istream_iterator<string>(cmdiss), 
      istream_iterator<string>(), 
      back_inserter<vector<string> >(tokens)); 
     std::cout << "cmd is " <<tokens.at(0) << std::endl; 
    } 

    //************************* 
    std::getline(std::cin, input); 
    istringstream iss(input); 
    if(input != ""){ 
     copy(istream_iterator<string>(iss), 
      istream_iterator<string>(), 
      back_inserter<vector<string> >(tokens)); 
     std::cout << "it is " << tokens.at(0) <<std::endl; 
     createInstruction(tokens); 
    } 

Répondre

0

Etes-vous sûr que la propriété editingMode est TRUE?

1

Il n'y a rien de mal avec le code. Il ne fait juste pas ce que vous pensez qu'il devrait :) Si vous voulez imprimer toute la ligne entrée plutôt que le premier mot, n'imprimez pas les jetons [0]; imprime la ligne d'entrée.

Les deux sections font la même chose:

  1. lire une ligne dans une chaîne
  2. créer un istream de cette ligne
  3. lire les mots de cette istream dans un tableau de chaînes appelées « jetons »
  4. imprimer le premier mot

tokens.at (0) est le premier mot, évidemment. Vérifiez tokens.size() ou itérez sur des jetons si vous voulez rechercher des arguments comme "8".

3

Peut-être vous avez un caractère de nouvelle ligne gauche dans le tampon d'entrée, d'une entrée plus tôt? C'est une erreur commune.

Disons que votre programme lit d'abord un entier avec cin >> x, puis une ligne avec getline (cin, cmdline). L'utilisateur tape un nombre entier suivi de la touche ENTRÉE. Le cin >> x lira l'entier, mais la touche ENTRÉE, interprétée comme un caractère de nouvelle ligne, sera laissée dans le tampon d'entrée.

Lorsque votre programme continue à lire une ligne complète avec getline (cin, cmdline), il lira la très courte ligne qui se compose uniquement de ce caractère de nouvelle ligne restante. Cela ressemble au programme "passe à la lecture suivante".

+0

Assez probable que ce soit le problème. Voir http://stackoverflow.com/questions/257091/how-do-i-flush-the-cin-buffer pour plus d'informations sur la suppression de l'entrée. Je suggère quelque chose comme la réponse de Martin York, car elle s'arrêtera quand elle atteindra la première ligne. – qid

0

Le problème consiste à mélanger >> extractions avec getline, en laissant une nouvelle ligne (ou une autre entrée) dans le tampon. Blindly using ignore cachera les erreurs de logique, telles que l'entrée de "42 abc" suivie de cin >> some_int; cin.ignore(...);. Qu'est-ce que vous avez à faire est « extraire » la ligne vide:

int main() { 
    using namespace std; 
    int n; 
    string s; 

    cout << "Enter a number: " 
    cin >> n >> blankline; // <--- 

    if (cin) { 
    cout << "Enter a line of text: "; 
    getline(cin, s); 
    } 

    if (!cin) { 
    clog << "Sorry, I can't do that.\n"; 
    return 1; 
    else { 
    cout << "Input successful, now processing values: " << n << s << '\n'; 
    } 
    return 0; 
} 

Heureusement, cela est easy:

template<class C, class T> 
std::basic_istream<C,T>& 
blankline(std::basic_istream<C,T>& s, 
      typename std::basic_istream<C,T>::char_type delim) { 
    if (s) { 
    typename std::basic_istream<C,T>::char_type input; 
    if (!s.get(input) && s.eof()) { 
     s.clear(s.eofbit); 
    } 
    else if (input != delim) { 
     s.putback(input); 
     s.setstate(s.failbit); 
    } 
    } 
    return s; 
} 

template<class C, class T> 
std::basic_istream<C,T>& blankline(std::basic_istream<C,T>& s) { 
    blankline(s, s.widen('\n')); 
    return s; 
}