2012-05-31 15 views
7

Ecco il codiceCome fare cin prendere solo numeri

double enter_number() 
{ 
    double number; 
    while(1) 
    { 

     cin>>number; 
     if(cin.fail()) 
     { 
      cin.clear(); 
      cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
      cout << "Invalid input " << endl; 
     } 
     else 
     break; 
     cout<<"Try again"<<endl; 
    } 
    return number; 
} 

mio problema è che quando entro in qualcosa di simile a 1x, poi 1 viene preso come ingresso senza notare il carattere che viene lasciato fuori per un altro run. Esiste un modo per farlo funzionare con qualsiasi numero reale, ad es. 1.8?

+0

Leggere tutto in una stringa e analizzare l'input di conseguenza? – Rhexis

+0

Usa cin.get() e poi controlla il carattere EOF? – Ansari

risposta

7

userei std::getline e std::string di leggere tutta la linea e poi rompere solo fuori dal giro, quando è possibile convertire l'intera linea di un doppio.

#include <string> 
#include <sstream> 

int main() 
{ 
    std::string line; 
    double d; 
    while (std::getline(std::cin, line)) 
    { 
     std::stringstream ss(line); 
     if (ss >> d) 
     { 
      if (ss.eof()) 
      { // Success 
       break; 
      } 
     } 
     std::cout << "Error!" << std::endl; 
    } 
    std::cout << "Finally: " << d << std::endl; 
} 
19

Quando cin incontra un input non può leggere correttamente nella variabile specificata (come l'immissione di un carattere in una variabile intera), entra in uno stato di errore e lascia l'input nel suo buffer.

Devi fare diverse cose per gestire correttamente questo scenario.

  1. È necessario verificare questo stato di errore.
  2. È necessario cancellare lo stato di errore.
  3. In alternativa, è necessario gestire i dati di input che hanno generato lo stato di errore, oppure svuotarlo e ripromettere l'utente.

Il seguente codice fornisce uno dei numerosi metodi per eseguire queste tre cose.

#include<iostream> 
#include<limits> 
using namespace std; 
int main() 
{ 

    cout << "Enter an int: "; 
    int x = 0; 
    while(!(cin >> x)){ 
     cin.clear(); 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
     cout << "Invalid input. Try again: "; 
    } 
    cout << "You enterd: " << x << endl;   
} 

si può solo passare in qualche grande valore alla cin.ignore come 1000 ed è probabile che si comportano esattamente lo stesso per tutti gli effetti.

È anche possibile testare cin dopo il tentativo di input e gestirlo in questo modo, ad esempio if (! Cin) {// ripulire l'errore}.

Partenza il riferimento istream per altre funzioni membro per gestire flusso di Stato: http://cplusplus.com/reference/iostream/istream/

+0

La riga 'cin.ignore' lo sta svuotando, giusto? – Jeff

+0

@Jeff Sì, scarica il buffer. Puoi anche usarlo quando usi cin con getline mentre prendi input mentre cin lascia il \ n 'nel buffer e non cancella (credo, non completamente sicuro, forse era cin.get) quindi getline viene solo delimitata momento che si collega al buffer di input mentre incontra il left over '\ n'. –

Problemi correlati