2010-07-18 4 views
15

Come dovrei controllare se l'input è davvero un doppio?come convalido l'input dell'utente come un doppio in C++?

double x; 

while (1) { 
    cout << '>'; 
    if (cin >> x) { 
     // valid number 
     break; 
    } else { 
     // not a valid number 
     cout << "Invalid Input! Please input a numerical value." << endl; 
    } 
} 
//do other stuff... 

Il codice sopra emette infinitamente comunicazione Invalid Input!, quindi non richiede per un altro ingresso. Voglio richiedere l'input, controllare se è legittimo ... se è un doppio, vai avanti ... se NON è un doppio, richiedi di nuovo.

Qualche idea?

+0

Assicuratevi di guardare la guida di formattazione prossima volta che fate un post. Grazie. – strager

+0

cosa intendi? cosa c'è di sbagliato nella formattazione? – Hristo

+0

Ho modificato il tuo post, ma prima della modifica il codice non era formattato. Fai clic su "modificato N minuti fa" per vedere il post originale. – strager

risposta

14

Prova questa:

while (1) { 
    if (cin >> x) { 
     // valid number 
     break; 
    } else { 
     // not a valid number 
     cout << "Invalid Input! Please input a numerical value." << endl; 
     cin.clear(); 
     while (cin.get() != '\n') ; // empty loop 
    } 
} 

questo cancella in pratica lo stato di errore, quindi legge e scarta tutto ciò che è stato inserito nella riga precedente.

+0

si trova all'interno del ciclo 'while (1)'? – Hristo

+0

Sì, all'interno del loop esistente. Ho appena riprodotto la parte interna. – casablanca

+0

Ok, questo funziona. Puoi spiegare la logica dietro il ciclo vuoto? Cosa sta succedendo esattamente là dentro? Cosa fa 'get()' fare? – Hristo

-3

Vorrei utilizzare scanf anziché cin.

La funzione scanf restituirà il numero di corrispondenze dalla stringa di destinazione. Per assicurarsi un doppio valida è stata analizzata, assicurarsi che il valore di ritorno di scanf è 1.

Edit:
Modificato fscanf a scanf.

+0

Voglio leggere dalla riga di comando ... non è 'fscanf' per leggere da un' FILE'? – Hristo

+0

La domanda è su come farlo usando 'cin'. – casablanca

+0

'scanf' fornirà la stessa funzionalità tranne che verrà letto da' stdin' invece di un oggetto file arbitrario. – advait

1

failbit verrà impostato dopo l'utilizzo di un operatore di estrazione in caso di errore di analisi, ci sono un paio di semplici funzioni di test good e fail che è possibile controllare. Sono esattamente l'opposto l'uno dall'altro perché gestiscono lo eofbit in modo diverso, ma questo non è un problema in questo esempio.

Quindi, è necessario cancellare failbit prima di riprovare.

Come dice casablanca, devi anche scartare i dati non numerici ancora rimasti nel buffer di input.

Quindi:

double x; 

while (1) { 
    cout << '>'; 
    cin >> x; 
    if (cin.good()) 
     // valid number 
     break; 
    } else { 
     // not a valid number 
     cout << "Invalid Input! Please input a numerical value." << endl; 
     cin.clear(); 
     cin.ignore(100000, '\n'); 
    } 
} 
//do other stuff... 
+0

questo sta ancora facendo sì che il ciclo infinito stampi "Ingresso non valido!" ... non richiede un altro input. – Hristo

+0

Cosa fa il 'cin.ignore()'? – Hristo

+0

Come il ciclo di Casablanca, getta via tutti i personaggi fino a includere la nuova riga per sbarazzarsi dei dati non numerici che hanno causato il fallimento della prima estrazione. –

0

Un modo è controllare l'uguaglianza dei numeri fluttuanti.

double x; 

while (1) { 
    cout << '>'; 
    cin >> x; 
    if (x != int(x)) { 
     // valid number 
     break; 
    } else { 
     // not a valid number 
     cout << "Invalid Input! Please input a numerical value." << endl; 
    } 
} 
+0

come verifica il tipo 'double'? – Hristo

+0

Questo controlla solo se l'input ha una parte frazionaria, che probabilmente non è ciò che intendeva la domanda. –

+0

Sì, molti di noi sanno cosa intendesse Hristo ma questa risposta risponde alla domanda che ha posto: "Come potrei controllare se l'input è davvero un doppio?" Interpretando questo come "Suppongo di ricevere numeri, come faccio a garantire che non siano numeri interi?" rende questa una risposta perfettamente utile. Non c'è bisogno di downvotare, imo. – chaosTechnician

0
#include <iostream> 
#include <string> 

bool askForDouble(char const *question, double &ret) 
{ 
     using namespace std; 
     while(true) 
     { 
       cout << question << flush; 
       cin >> ret; 
       if(cin.good()) 
       { 
         return true; 
       } 
       if(cin.eof()) 
       { 
         return false; 
       } 
       // (cin.fail() || cin.bad()) is true here 
       cin.clear(); // clear state flags 
       string dummy; 
       cin >> dummy; // discard a word 
     } 
} 

int main() 
{ 
     double x; 
     if(askForDouble("Give me a floating point number! ",x)) 
     { 
       std::cout << "The double of it is: " << (x*2) << std::endl; 
     } else 
     { 
       std::cerr << "END OF INPUT" << std::endl; 
     } 
     return 0; 
} 
+1

La convalida degli input avrebbe dovuto essere un compito più facile da fare. Rende molto difficile insegnare ai neofiti e aiutarli a godersi quello che stanno facendo. Mi piacerebbe vedere un tutorial antiproiettile e ancora utile su cin e cout per i neofiti. – Notinlist

0
bool is_double(double val) 
{ 
bool answer; 
double chk; 
int double_equl = 0;  
double strdouble = 0.0; 
strdouble = val;   
double_equl = (int)val; 
chk = double_equl/strdouble; 
if (chk == 1.00) 
{ 
answer = false; // val is integer 
return answer; 
} else { 
answer = true; // val is double 
return answer; 
} 
}