Ignorando EOF sul std :: cin in C ++
Domanda
Ho un'applicazione che implementa una shell interattiva, simile a come il pitone console / opere IRB. Il problema ora è che se l'utente preme accidentalmente ^D
EOF viene rilasciato e la mia getline()
chiamata restituisce una stringa vuota che ho tratto come "nessun input" e visualizzare nuovamente il prompt.
Ciò si traduce poi in un ciclo infinito che stampa la richiesta.
Ora in Python vorrei risolvere il problema con la cattura EOFError
, ma in C ++ non fa eccezione viene sollevata ho potuto prendere e non sembra essere una regolazione sul cin
ignorare EOF.
Eventuali suggerimenti?
Soluzione 2
La corretta soluzione grazie a litb:
if (!getline(std::cin, str)) {
std::cin.clear();
std::cout << std::endl;
}
Altri suggerimenti
Se non si poteva leggere nulla, imposta il failbit
. Basta provare il flusso in una condizione if, e cancellare il bit:
if(!getline(std::cin, myline)) {
std::cin.clear();
std::cout << "you should enter something" << std::endl;
}
Internamente, la sequenza è in questo modo nel tuo caso:
- Wait sul terminale per una stringa. Terminale bloccherà finché l'utente emette una nuova riga. Due casi di errore probabili possibili
- L'utente preme subito EOF. Questo renderà
getline
leggere nulla, e sarà impostare laeofbit
eistream::sentry
. - Ingressi utente qualcosa e poi preme EOF. Questo renderà
clear()
consumare qualcosa e poi lo colpisce EOF durante il tentativo di ottenere il carattere successivo. Questa causa <=> da impostare.
- L'utente preme subito EOF. Questo renderà
- Si cercherà di leggere qualcosa di nuovo. La funzione di estrazione creerà un oggetto di tipo <=> che controlla in quale stato il flusso è. Se uno qualsiasi dei errorbits sono impostati, causerà la funzione di estrazione per ritornare immediatamente. Che ha causato prima che il ciclo infinito.
Una chiamata a <=> cancella tutti i bit di errore, e si può andare a leggere di nuovo le tue cose.
Il getline()
funzione segnala errori utilizzando il seguente bit:
- eofbit
- failbit
- badbit
Prova a controllare questi prima di procedere.
http://www.horstmann.com/cpp/pitfalls.html
È possibile utilizzare il codice:
while (cin)
{ int x;
cin >> x;
if (cin) a.push_back(x);
}
Ok, in altre risposte utilizzando cin.clear () è stato descritto come una possibile soluzione.
Un altro trucco è di usare altri mezzi per elaborare l'input dalla console rispetto allo standard tipico impostando il terminale ad un altro modo in modo da poter elaborare Ctrl + D direttamente. In modalità RAW o altri, si guadagna l'accesso più diretto alle sequenze di input e di controllo dal lato utente (come Ctrl + D o Ctrl + C) non vengono gestiti più ripetitivo.
Alcune librerie si possono tentare di raccogliere maggiori informazioni (o anche di risparmiare tempo di codifica):
- GNU Readline
- Terminal Utile I Biblioteca / O ½
- NCurses (che è molto potente)
½ Potete trovare alcune informazioni relative al problema nella documentazione qui .