2013-01-28 17 views
5

Quindi sto sperimentando con il tentativo di aggiungere il nome e il cognome in una doppia lista concatenata. Ho diversi file di testo di diverse lunghezze con il formato "stringa, stringa" e sto usando la lista> per memorizzare i miei dati.confusione su liste e coppie

Sto usando questo codice:

typedef std::list< std::pair<string,string> > listPair; 

...

list<pair<string, string> > mylist; 
ifstream myFile; 
myFile.open("20.txt"); 

pair<string, string> stuff; 
while (myFile >> stuff.first >> stuff.second) 
{ 
    mylist.push_back(stuff); 
} 

listPair::iterator iter = mylist.begin(); 

for(;iter != mylist.end();iter++) 
{ 
    string s = (*iter).first; 
    cout << s << endl; 
    string c = (*iter).second; 
    cout << c << endl; 
} 

ora il problema che sto avendo è che in primo luogo, non viene aggiunto l'ultimo elemento della lista. come ogni file manca la linea di fondo, quindi è un po 'di confusione.

inoltre, sto facendo un "mylist.size()" per garantire che tutti i nomi siano stati aggiunti, e mi confonde perché dire per un file di testo contenente 99 nomi, cioè 99 righe di testo, dirà (non dimenticando si legge solo in 98 a causa della mancanza dell'ultima riga) che la lista ha dimensione 48.

PERCHÉ 48? E 'qualcosa da fare perché ho fatto delle coppie, che comunque non avrebbero senso come se non stesse leggendo in coppia ci sarebbe in realtà il doppio di circa, dal momento che le coppie sono solo per prendere il nome e il cognome come un valore.

La mente mi dava fastidio.

ancora una volta grazie per tutto il vostro aiuto!

+0

Forse stai cercando 'getline'? –

+2

Proprio come una nota a margine, come contenitore per uso generico dovresti usare 'vector' piuttosto che' list'. Dal modo in cui lo stai usando, non vedo la necessità di un 'elenco' qui. –

+0

Potresti aggiungere il file di input '20.txt' (o almeno un estratto)? Forse il tuo input non è formattato correttamente. – Zeta

risposta

5

ho la sensazione che il file in realtà non ha spazi tra i valori come hai descritto, in modo che appaia simile al seguente:

one,two 
three,four 
five,six 
seven,eight 
nine,ten 

Se si dovesse eseguire il programma su questo, la dimensione di list sarà 2 (floor(number_of_lines/2), che per te darebbe 48) e l'ultima riga non sarà stata inserita nello list. Perché?

In primo luogo, ogni chiamata a std::ifstream::operator>>(std::string&) verrà estratta finché non raggiunge uno spazio bianco. In questo caso, il primo spazio bianco sulla prima riga è il \n alla fine di esso. Quindi, nella prima iterazione, stuff.first sarà "one,two" e quindi la riga successiva verrà letta in stuff.second, rendendola "three,four". Questo viene quindi inserito nel list. Le due righe successive vengono lette allo stesso modo, dandoti la coppia {"five,six","seven,eight"}. Alla successiva iterazione, il primo operator>> estrarrà "nine,ten" e il secondo non riuscirà, causando la condizione while e l'ultima riga da scartare.

Anche se si dispone di spazi, si otterrebbero virgole nello first di ogni pair, che non è certamente quello che si desidera.

Il modo più bello per affrontare un problema come questo è quello di utilizzare std::getline per estrarre una linea, e quindi analizzare quella linea a seconda dei casi:

std::string line; 
std::pair<std::string, std::string> line_pair; 
while (std::getline(myFile, line)) { 
    std::stringstream line_stream(line); 
    std::getline(line_stream, line_pair.first, ','); 
    std::getline(line_stream, line_pair.second); 
    mylist.push_back(line_pair); 
} 

mi consiglia anche di utilizzare std::vector meno che non abbiate una buona ragione per usare std::list.

+0

grazie, questo è esattamente il mio problema e ha funzionato perfettamente! gosh impara qualcosa di nuovo ogni giorno haha –

-1

L'operatore > > su ifstream tratta newline come un altro token. Quindi leggerà probabilmente la prima e la seconda parola come da normale dalla prima riga, ma la terza lettura del token è la nuova riga sulla prima riga.

Provare a usare getline per "mangiare" anche il newline.

+3

Gli estrattori trattano le nuove linee proprio come qualsiasi altro spazio bianco. Non devi saltare intorno a loro se usi costantemente l'operatore <>. –