c ++ getline () non aspetta l’input dalla console quando viene chiamato più volte

Sto tentando di ottenere alcuni parametri di input dell’utente dalla console, due stringhe, due inte e una doppia. Il codice pertinente che sto cercando di usare è questo:

#include  #include  using namespace std; // ... string inputString; unsigned int inputUInt; double inputDouble; // ... cout << "Title: "; getline(cin, inputString); tempDVD.setTitle(inputString); cout << "Category: "; getline(cin, inputString); tempDVD.setCategory(inputString); cout <> inputUInt; tempDVD.setDuration(inputUInt); cout <> inputUInt; tempDVD.setYear(inputUInt); cout <> inputDouble; tempDVD.setPrice(inputDouble); 

Tuttavia, durante l’esecuzione del programma, anziché attendere l’immissione del primo inputString, il codice non si arresta fino alla seconda chiamata getline (). Quindi l’output della console assomiglia a questo:

Titolo: Categoria:

con il cursore che appare dopo la categoria. Se inserisco ora, il programma salterà in avanti all’input dell’anno, non permettendomi di inserire più di una stringa. Cosa sta succedendo qui?

Il problema è che si stanno mixando le chiamate a getline () con l’uso dell’operatore >>.

Ricorda che l’operatore >> ha ignorato lo spazio bianco iniziale, quindi continuerà correttamente oltre i limiti delle linee. Ma smette di leggere dopo che l’input è stato recuperato con successo e quindi non ingoierà i caratteri “\ n” finali. Quindi se usi un getline () dopo un >> di solito ottieni la cosa sbagliata a meno che tu non stia attento (per prima cosa rimuovi il carattere ‘\ n’ che non è stato letto).

Il trucco è non usare entrambi i tipi di input. Scegli quello appropriato e attenersi ad esso.

Se sono tutti numeri (o oggetti che funzionano bene con l’operatore >>), basta usare l’operatore >> (La stringa nota è l’unico tipo fondamentale che non è simmetrico con l’input / output (cioè non gioca bene)).

Se l’input contiene stringhe o una combinazione di elementi che richiedono getline (), utilizzare solo getline () e analizzare il numero fuori dalla stringa.

 std::getline(std::cin, line); std::stringstream linestream(line); int value; linestream >> value; // Or if you have boost: std::getline(std::cin, line); int value = boost::lexical_cast(line); 

È necessario svuotare il buffer di input. Può essere fatto con cin.clear(); cin.sync(); cin.clear(); cin.sync(); .

Puoi usare

 cin.ignore(); 

o come @kernald ha menzionato l’uso

 cin.clear(); cin.sync(); 

prima di usare getline ()

Usa cin.clear() come accennato e usa la corretta gestione degli errori:

  cin.clear(); cin.sync(); cout << "Title: "; if (!getline(cin, inputString)) exit 255; tempDVD.setTitle(inputString); cout << "Category: "; if (!getline(cin, inputString)) exit 255; tempDVD.setCategory(inputString); cout << "Duration (minutes): "; if (!(cin >> inputUInt)) exit 255; tempDVD.setDuration(inputUInt); cout << "Year: "; if (!(cin >> inputUInt)) exit 255; tempDVD.setYear(inputUInt); cout << "Price: $"; if (!(cin >> inputDouble)) exit 255; tempDVD.setPrice(inputDouble); 

Mescolare getline () con flussi di input in genere è una cosa brutta da fare. È teoricamente ansible gestire manualmente i buffer sporchi rimasti utilizzando gli stream, ma è un dolore inutile che dovrebbe essere assolutamente evitato.

Stai meglio usando una libreria di console per afferrare i tuoi input, in questo modo il lavoro sporco può essere astratto per te.

Dai un’occhiata a TinyCon. Puoi semplicemente utilizzare il metodo statico tinyConsole :: getLine () in sostituzione delle tue chiamate getline e stream e puoi utilizzarlo tutte le volte che vuoi.

Puoi trovare informazioni qui: https://sourceforge.net/projects/tinycon/

cin.sync (); usa questo invece di cin.ignore (funziona meglio.