2013-04-26 11 views
8

Ho trovato questo collegamento a http://www.parashift.com/c++-faq-lite/istream-and-ignore.htmlEsempio C++: non è in grado di capire cosa si sta facendo?

che mostra "Come posso ottenere std :: cin per saltare caratteri di input non validi?"

Use std::cin.clear() and std::cin.ignore(). 

#include <iostream> 
#include <limits> 

int main() 
{ 
    int age = 0; 

    while ((std::cout << "How old are you? ") 
     && !(std::cin >> age)) { 
    std::cout << "That's not a number; "; 
    std::cin.clear(); 
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    } 

    std::cout << "You are " << age << " years old\n"; 
    ... 
} 
Of course you can also print the error message when the input is out of range. For example, if you wanted the age to be between 1 and 200, you could change the while loop to: 
    ... 
    while ((std::cout << "How old are you? ") 
     && (!(std::cin >> age) || age < 1 || age > 200)) { 
    std::cout << "That's not a number between 1 and 200; "; 
    std::cin.clear(); 
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    } 
    ... 
Here's a sample run: 
How old are you? foo 
That's not a number between 1 and 200; How old are you? bar 
That's not a number between 1 and 200; How old are you? -3 
That's not a number between 1 and 200; How old are you? 0 
That's not a number between 1 and 200; How old are you? 201 
That's not a number between 1 and 200; How old are you? 2 
You are 2 years old 

Non riesco a capire come funziona> Qualcuno può spiegare per favore?

ho dei dubbi con:

while ((std::cout << "How old are you? ") 
      && !(std::cin >> age)) 

Come mai controllando la voce valida? Voglio dire fare espressioni "std :: cout < <" Quanti anni hai? "E"! (Std :: cin >> età) ", restituisce true o false che sono ANDed?

un'altra cosa che è confondendo è l'utilizzo,

std::cin.clear(); 
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

Quali sono lì scopo? cercato su google su queste funzioni, ma ancora non mi è chiaro. in particolare, std::numeric_limits<std::streamsize>::max()

Può uno aiuto? Grazie

+0

cin.clear() e cin.ignore() è per la prevenzione cin per essere saltato, (se non fa male). Per il primo momento, immagino che sia quello sbagliato che viene chiesto. – cakil

risposta

10

Gli operatori di inserimento ed estrazione << e >> sugli stream restituiranno un riferimento al flusso stesso. Ecco perché si può stringa insieme inserimenti in questo modo:

std::cout << "Hello, " << "World!"; 

Prima std::cout << "Hello, " restituisce un riferimento alla std::cout e poi ci sono l'equivalente di std::cout << "World!".

Gli stream possono anche essere convertiti in bool. Questo fondamentalmente controlla che lo stato del flusso sia ancora a posto. Niente ha fallito. Ad esempio, si potrebbe fare questo:

if (std::cin) // ... 

Questo avrebbe controllato se il flusso std::cin è ancora in buono stato.

Ora diamo un'occhiata al codice hai chiesto:

while ((std::cout << "How old are you? ") 
     && !(std::cin >> age)) 

L'inserimento in std::cout non causerà un fallimento. L'unica ragione per cui è incluso qui è che si verifica ogni volta prima dell'input a age. L'alternativa sarebbe quella di posizionarlo una volta prima del while e una volta alla fine del corpo while.

Dopo aver effettuato l'inserimento su std::cout, verrà valutato !(std::cin >> age). Ciò consentirà all'utente di fornire un age. Poi due cose possono accadere:

  1. Se questo non riesce, in qualche modo (forse l'utente immette caratteri piuttosto che un intero), poi il fail bit viene impostato. Ciò significa che il risultato di std::cin >> age verrà convertito in un bool che sarà false. Lo ! lo invertirà in true. Quindi, poiché sia ​​la prima che la seconda condizione erano vere, il corpo del ciclo while verrà eseguito, indicando all'utente che è stato inserito un valore non valido e il ciclo verrà ripetuto di nuovo.

  2. se l'ingresso ha successo, il risultato di std::cin >> age sarà true e ! girerà a false. Ciò significa che il corpo del ciclo while non verrà eseguito e non comunicherà all'utente che ha inserito il valore errato.

Ora diamo un'occhiata a:

std::cin.clear(); 
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

questo accade solo nel caso di cui sopra 1, quando l'ingresso non è riuscita. Se uno stream entra in uno stato di errore, non accetterà ulteriori inserimenti o estrazioni fino a quando lo stato non sarà stato cancellato. questo è ciò che fa clear(). Quindi la chiamata a ignore dice di estrarre tutti i caratteri fino al successivo \n nello stream e scartarli. Questo elimina l'input non valido dallo stream.

+0

"Quindi la chiamata da ignorare dice di estrarre tutti i caratteri fino al prossimo \ n nello stream e scartarli. Questo elimina l'input non valido dallo stream." - significa che il carattere di nuova riga '\ n' è ancora nel flusso, non ci vorrà '\ n' come input nella successiva iterazione di "Quanti anni hai?" –

+0

@GauravK Ci scusiamo, dovrebbe essere "fino a includere il prossimo' \ n' ". –

+0

No, voglio solo sapere se ignore() scarta anche il delim, perché quello che ho letto che se Delim è EOF non viene scartato, se è diverso da 'EOF' - Viene estratto e scartato anche? –

0

Come age è un intero

(std::cin >> age) 

tenta di analizzare in ingresso per ottenere un numero intero valido, se può restituire true, altrimenti restituisce false.

Per conoscere cin.ignore, lo farà ..

Estratti e scarta i caratteri dal flusso di input fino a quando ea compreso delim.

+0

-47 è un numero intero valido, ma non un'età valida. Quindi il test è rotto. – trojanfoe

+0

quindi, dovrebbe ricontrollarlo.Come ho detto, controlla la validità come un numero intero non come un'età. – deepmax

0

std::numeric_limits consente di ottenere il numero massimo che può rientrare in un determinato tipo.

Nel tuo esempio, è passato alla funzione ignore(), che in pratica significa ignorare anticipatamente ogni carattere di nuova riga.

+0

Che dire di "std :: streamsize"? –

+0

È il tipo utilizzato per contenere la dimensione dei dati all'interno del flusso. [Questo è veramente facile da trovare] (http://en.cppreference.com/w/cpp/io/streamsize). –

1
while ((std::cout << "How old are you? ")  && !(std::cin >> age)) 

cout è un oggetto globale di classe ostream e cin è un oggetto globale di classe istream

Questi scopi vengono utilizzati insieme agli operatori di overload << (definito in ostream) e >> (definito in istream) per prendere input (chiamando le funzioni definite per questi operatori)

Il tipo di reso di operator<< è di tipo ostream& e quello di operator>> è istream&. Questi vengono poi convertiti in valori booleani. Vedi this.

Controllare this troppo per cin.ignore() e cin.clear()

+0

Si prega di non collegare a 'cplusplus.com'. –

+0

@bartek, Yeps personalmente non mi piacciono ma poi non sono riuscito a trovare la pagina corretta su cpprefrence. Lo aggiornerò una volta capito, oh bene, l'hai fatto. Grazie –

+0

@BartekBanachewicz Cosa c'è di sbagliato in cpluscplus.com? Hanno informazioni sbagliate? (Non lo so, lo chiedo davvero.) – Chani

Problemi correlati