2013-09-02 16 views
5

Nowość w C++. Problemy z poprawnie zapętlaniem podczas obsługi błędów. Próbuję sprawdzić, czy dane wejściowe użytkownika są liczbą całkowitą i są dodatnie.C++ Sprawdzanie liczby całkowitej.

do{ 
    cout << "Please enter an integer."; 
    cin >> n; 

    if (cin.good()) 
    { 
     if (n < 0) {cout << "Negative.";} 
     else {cout << "Positive.";} 
    } 
    else 
    { 
     cout << "Not an integer."; 
     cin.clear(); 
     cin.ignore(); 
    } 
}while (!cin.good() || n < 0); 

cout << "\ndone."; 

Po wpisaniu liczby niecałkowitej, pętla ulega złamaniu. Czuję, że nie rozumiem nieodłącznego użycia cin.clear() i cin.ignore() i statusu cin podczas tej pętli. Jeśli usuniemy cin.ignore(), pętla stanie się nieskończona. Dlaczego to? Co mogę zrobić, aby przekształcić go w elegancko funkcjonującą pętlę? Dziękuję Ci.

+1

pomocą debuggera. –

Odpowiedz

5

W Twojej gałęzi niecałkownikowej wywołujesz dalsze metody cin, dzięki czemu cin.good() zostaje zresetowany do wartości true.

Można zmienić swój kod na coś takiego:

while(1) { // <<< loop "forever" 
    cout << "Please enter an integer."; 
    cin >> n; 

    if (cin.good()) 
    { 
     if (n < 0) {cout << "Negative.";} 
     else { cout << "Positive."; break; } 
    }       // ^^^^^ break out of loop only if valid +ve integer 
    else 
    { 
     cout << "Not an integer."; 
     cin.clear(); 
     cin.ignore(INT_MAX, '\n'); // NB: preferred method for flushing cin 
    } 
} 

cout << "\ndone."; 

czy można uprościć go jeszcze tak:

while (!(cin >> n) || n < 0) // <<< note use of "short circuit" logical operation here 
{ 
    cout << "Bad input - try again: "; 
    cin.clear(); 
    cin.ignore(INT_MAX, '\n'); // NB: preferred method for flushing cin 
} 

cout << "\ndone."; 
+1

Działa to fantastycznie, dziękuję! Nie sądziłem nawet, że mój wybór pętli powstrzymuje mnie. Doceniam pomoc i wyjaśnienie. – xavi

+0

Czy druga wersja nie zakończyłaby pętli po wprowadzeniu przez użytkownika śmieci (np. Musisz rozpakować (lub zignorować) śmieci przed zapętleniem (ale po 'clear()'). –

+0

@ James: dobry połów - dzięki - Naprawiłem to teraz (i faktycznie przetestowałem!). –

3
int n; 

while (!(cin >> n)||n<0)//as long as the number entered is not an int or negative, keep checking 
{ 
cout << "Wrong input. Please, try again: "; 
cin.clear();//clear input buffer 

} 
//only gets executed when you've broken out of the while loop, so n must be an int 
cout << "Positive."; 

cout << "\ndone.";//finished! 

Powinno robić, co chcesz.

+0

który nie wyjaśnia, co się stało ... –

+0

@NoIdeaForName punkt wzięty, będę komentować w wyjaśnieniach – imulsion

+0

teraz, gdy go zbadam, to nawet nie robi tego, co chciał zrobić. jeśli wejście jest dobre, powinieneś wyjść tylko wtedy, gdy jest ujemny ... –