2010-03-05 4 views
4

Le bug commence à cin.getline (string, 25, '\ n'); ou la ligne en dessous (strtod). Si j'utilise cin, ça marche, sauf que je ne peux pas quitter. Si je tape tout ce qui n'est pas un double, une boucle infinie s'exécute. Besoin d'aide pour. Fondamentalement, la première itération s'exécute, ne demande pas d'entrée, donc l'utilisateur obtient les questions de mathématiques mal. La deuxième itération fonctionne bien. Et la prochaine va bien aussi. Si je recule, en utilisant q, je suis renvoyé au mode-chooser. Après avoir choisi un mode, le bug réapparaît pour la première itération. Prochaines itérations c'est parti.La première itération de la première boucle échoue toujours à prendre une entrée. 2+ boucles fonctionnent bien

int main() 
{ 
    char choice, name[25], string[25], op; 
    int operator_number, average, difference, first_operand, second_operand, input, answer, total_questions = 0, total_correct = 0; 
    double dfirst_operand, dsecond_operand, dinput, danswer, percentage; 
    bool rounding = false; 

    srand (time(NULL)); 

    cout << "What's your name?\n"; 
    cin.getline (name, 25, '\n'); 
    cout << '\n' << "Hi, " << name << "."; 

    do { 
    do { 
    cout << "\nWhich math operations do you want to practice?\n 1. Addition\n 2. Subtraction\n 3. Multiplication\n 4. Division\n 5. Mixed\n 6. Difference of squares multiplication.\nChoose a number (q to quit).\n"; 
    cin >> choice; 
    } while(choice < '1' || choice > '6' && choice!= 'q'); 

    cout << "\n"; 

    switch(choice) { 
    case '1': 
      while(string[0]!= 'q') { 
       dfirst_operand = rand() % 15 + 1; 
       dsecond_operand = rand() % 15 + 1; 
       danswer = dfirst_operand + dsecond_operand; 
       cout << dfirst_operand << " + " << dsecond_operand << " equals?\nEnter q to quit.\n"; 
       cin.getline (string, 25, '\n'); 
       dinput = strtod(string,NULL); 
       //cin >> dinput; 
       if(string[0]!='q') { 
       ++total_questions; 
       if(dinput==danswer) { 
        ++total_correct; 
        cout << "Correct. " << total_correct << " correct out of " << total_questions << "."; 
       } else { 
        cout << "Wrong. " << dfirst_operand << " + " << dsecond_operand << " equals " << danswer << ".\n" << total_correct << " correct out of " << total_questions << "."; 
       }; 
       percentage = floor(10000 * (float) total_correct/total_questions)/100; 
       cout << ' ' << percentage << "%.\n\n"; 
       } 
      } 
      break; 
      } 
    } while(choice!='q'); 
    return 0; 
} 
+0

Lien obligatoire vers C++ FAQ Lite: http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.2 – indiv

Répondre

1

Le problème est cette ligne:

cin >> choice; 

Cette ligne traite le tampon d'entrée pour l'entrée de caractères qui peut être converti en un nombre entier. Donc, si vous entrez:

2<newline> 

La chaîne « 2 » est converti, et <newline> reste dans la mémoire tampon d'entrée; donc le cin.getline() suivant est satisfait immédiatement.

C'est aussi pourquoi la suggestion de JonH ne fonctionne pas, vous devez purger le tampon d'entrée après l'entrée cin << choice. Une alternative est d'utiliser cin.getline() pour toutes les entrées (ou mieux, use :: getline() qui fonctionne sur std :: string plutôt que C-strings), puis d'analyser cette entrée en utilisant un objet std :: istringstream quand vous avez besoin d'une numérisation d'entrée formatée.

Toutefois, si vous devez utiliser cin.ignore() pour résoudre ce problème, vous devriez le faire ainsi:

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') ; 

où std :: numeric_limits est défini dans l'en-tête. Votre solution fait confiance à l'utilisateur pour ne pas entrer plus de 25 caractères. Ce n'est pas une hypothèse très sûre.

+0

J'ai utilisé votre méthode et c'est parfait. C'est très sûr à utiliser et ça fonctionne bien. Merci. – Duc

0

Essayez de lancer une cin.ignore() juste après ou avant la cin.getline().

+0

Merci pour votre réponse. Il a corrigé ce bug, mais il en crée un autre. J'ai ajouté cin.ignore(); après cin.getline (chaîne, 25, '\ n'); et maintenant il ne va pas enregistrer les bonnes réponses. Pourriez-vous expliquer ce que cin.ignore fait? J'ai lu un peu à ce sujet, mais je suis toujours confus quant à ce qu'il fait. – Duc

+1

Down-voté parce que c'est juste incorrect (même avec l'édition de Changeling), et se lit comme une «supposition». Ne pas * essayer *; faire. – Clifford

+0

@Clifford - Ce n'est pas une supposition, vous pouvez toujours utiliser cin.ignore(). -1 à vous parce que votre message est juste un GUESS – JonH

Questions connexes