2012-03-22 19 views
5

Ho un programma del genere:Perché questo programma va in loop infinito?

#include <stdlib.h> 
#include <iostream> 

static int pswd=0; 

int main() { 

    do { 
     std::cout<<"I need your password:"<<std::endl;   
     std::cin>>pswd; 
    } while (pswd!=3855); 

    std::cout<<"Congratulations! Your password is correct! Your soul is free again!"<<std::endl; 
} 

E devo, può essere, una domanda stupida. Quando inserisco valori non validi (con simboli non numerici o valori maggiori di int) il programma passa in loop continuo senza leggere alcuna informazione dalla console.

I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
     ... 

Perché questo programma va in loop infinito?

risposta

10

Perché dopo un input non valido, il flusso è in stato fallito e tutte le ulteriori operazioni di immissione sono non opzionali. Devi sempre controllare il risultato dell'operazione di input.

do { 
    std::cout<<"I need your password:"<<std::endl;   
    if (!(std::cin >> pswd)) { 
     // clear error flags 
     std::cin.clear(); 
     // discard erroneous input (include <limits>) 
     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    } 
} while (pswd!=3855); 
+1

Questo tratterà l'input non numerico come password corretta. – interjay

+0

Forse sarebbe meglio assorbire l'input fallito invece di un 'break' –

+0

Non ho davvero prestato attenzione alla semantica del ciclo. Si tratta principalmente di illustrare la gestione degli errori. –

1

esso prova a leggere un int ma può dare uno sguardo nel buffer da STDIN. Si accorge che non si dispone di uno int in modo che lo cin>> non riesca. (Vedi fail bit).

Quindi va ancora in giro. È necessario verificare la mancata conversione del tipo.

1

Sono quasi sicuro di voler leggere in una stringa qui, poiché non c'è nulla per controllare ciò che l'utente sta digitando.

si desidera leggere in un buffer char (quella sotto supporta 256 caratteri) e poi confrontarlo con la password che stai cercando utilizzando strcmp:

#include <stdlib.h> 
#include <iostream.h> 

static int pswd=0; 
static char buffer[256]; 

int main() 
{ 
    do 
    { 
     std::cout<<"I need your password:"<<std::endl;   
     std::cin>>buffer; 
    } 
    while (strcmp("3855", buffer)); 
    std::cout<<"Congratulations! Your password is correct! Your soul is free again!"<<std::endl; 
} 

notare che strcmp restituisce 0 quando due stringhe incontro.

+0

Grazie. È una buona idea. Ma voglio capire questo fenomeno esclusivamente a fini educativi. –

+1

Questo è un potenziale overflow del buffer, usare invece 'std :: string'. Inoltre, l'intestazione da includere è ''. – interjay

+0

Questo è abbastanza vero, quindi ho sottolineato che legge solo 256 caratteri! Ma sì, dovrebbe usare std :: string –