2012-02-23 3 views
6

Il mio codice simile a questo,getline (cin, aString) che riceve in ingresso senza un altro entrare

string aString; 
cin >> aString; 
cout << "This is what cin gets:" << aString << endl; 
getline(cin, aString); 
cout << "This is what getline(cin, <string>) gets:" << aString << endl; 

Ogni volta che mi sono imbattuto, io do ingressi come, "12", ottengo "12" e "" .

Mi chiedo perché la linea venga ricevuta senza l'input dell'utente.

Posso capire quando inserisco qualcosa come "12 24", cin otterrà "12" e getline dovrebbe ottenere il resto. (Inoltre, se si può rispondere, lo spazio intermedio viene considerato come una fine per cin, quindi perché viene passato a getline?)

Appena iniziando su una stringa su C++ quindi per favore non renderlo troppo difficile . Grazie.

+0

Se hai già ricevuto l'input non c'è altro da ottenere a meno che non ci sia più input ... – AJG85

risposta

12

Quando si mescolano estrazione flusso di serie con getline, a volte si hanno getline restituisce la stringa vuota. La ragione di ciò è che se leggi l'input con >>, il carattere di nuova riga immesso dall'utente per segnalare che sono stati eseguiti non viene rimosso dal flusso di input. Di conseguenza, quando si chiama getline, la funzione leggerà il carattere di nuova riga rimanente e restituirà la stringa vuota.

Per risolvere questo problema, sia costantemente utilizzare getline per il vostro input oppure usa il flusso manipolatore ws per estrarre lo spazio vuoto in più dopo una lettura:

cin >> value >> ws; 

Questa mangerà il ritorno a capo, che fissa il problema.

Spero che questo aiuti!

7

questo è ciò che ottengo:

std::string str; 
std::cin >> str; //hello world 
std::cout << str; //hello 

questo è perché l'operatore flusso tokenizza su spazio bianco

std::string str; 
std::getline(std::cin, str); //hello world 
std::cout << str; //hello world 

si ottiene la linea completa, getline() lavora fino a trovare il prima estremità di linea e restituisce quel valore come una stringa.

Tuttavia, durante la tokenizzazione, se sono presenti caratteri (ad esempio un '\ n') lasciati nello stream, a questi sarà possibile accedere quando viene chiamato getline, sarà necessario cancellare lo stream.

std::cin.ignore(); 
1

"cin >> x" non consuma il carattere di nuova riga dal flusso di input, quindi la riga successiva che si recupera con getline conterrà una stringa vuota. Un modo per risolverlo è usare la linea di fondo per recuperare l'input riga per riga e usare un stringstream per tokenizzare ogni linea. Dopo aver estratto tutti gli input dallo stringstream, l'importante è chiamare stringstream :: clear() per cancellare il flag EOF impostato sullo stringstream per poterlo riutilizzare più avanti nel codice.

Ecco un esempio:

#include <iostream> 
#include <sstream> 
#include <string> 

using namespace std; 

int main() { 
    string line; 
    stringstream ss; 
    getline(cin, line); 
    ss << line; 
    int x, y, z; 
    //extract x, y, z and any overflow characters 
    ss >> x >> y >> z >> line; 
    ss.clear(); 
    //reuse ss after clearing the eof flag 
    getline(cin, line); 
    ss << line; 
    //extract new fields, then clear, then reuse 
    //... 
    return 0; 
} 

A seconda della lunghezza di ogni linea di ingresso, ottenendo tutta la linea alla volta e la trasformazione in memoria è probabilmente più efficiente di fare console IO su ogni pedina che si desidera estrarre dallo standard input.