2013-09-02 31 views
5

Nuovo in C++. Problemi durante il loop durante la gestione degli errori. Sto cercando di verificare se l'input dell'utente è un numero intero ed è positivo.C++ Controllo di un numero intero.

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."; 

Quando si immette un numero intero, il ciclo si interrompe. Mi sembra di fraintendere l'uso intrinseco di cin.clear() e cin.ignore() e lo stato di cin durante questo ciclo. Se rimuovo lo cin.ignore(), il loop diventa infinito. Perchè è questo? Cosa posso fare per rendere questo ciclo elegantemente funzionante? Grazie.

+1

utilizza un debugger. –

risposta

5

Nel ramo non intero si invocano ulteriori metodi cin in modo che cin.good() venga ripristinato su true.

Si potrebbe modificare il codice per qualcosa di simile:

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."; 

o è possibile semplificare ancora di più in questo modo:

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

Questo funziona in modo fantastico, grazie! Non pensavo nemmeno che la mia scelta del loop mi trattenesse. Apprezzo l'aiuto e la spiegazione. – xavi

+0

La seconda versione non produrrebbe un ciclo infinito una volta che l'utente ha inserito la posta indesiderata (ad esempio qualcosa come "abc")? È necessario estrarre (o ignorare) la posta indesiderata prima del ciclo (ma dopo 'clear()'). –

+0

@James: buona cattura - grazie - L'ho risolto ora (e in effetti lo ho testato!). –

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! 

Dovrebbe fare quello che vuoi.

+0

che non spiega cosa è successo ... –

+0

@NoIdeaForName punto preso, commenterò nelle spiegazioni – imulsion

+0

ora che lo esamino, non fa nemmeno quello che ha chiesto di fare. se l'input è buono dovresti lasciarlo solo se è negativo ... –

Problemi correlati