2012-03-30 16 views
6

il seguente codice non si comporta come mi aspetterei. Per favore aiutami a capire come funziona.con ifstream

#include <algorithm> 
#include <iterator> 
#include <fstream> 
#include <vector> 
#include <string> 
using namespace std; 

struct user 
{ 
     string name; 
     string age; 
     string id; 
}; 

istream& operator>>(istream& is, user& s) 
{ 
     getline(is, s.name, ':'); 
     getline(is, s.age, ':'); 
     getline(is, s.id); 

     return is; 
} 

int main(int argc, char* argv[]) 
{ 
     ifstream file("file.txt"); 
     vector<user> vec; 
     copy(istream_iterator<user>(file), istream_iterator<user>(), back_inserter(vec)); 

     return 0; 
} 

Il mio operatore personalizzato >> è chiamato due volte, ma mi sarei aspettato di essere chiamato solo una volta perché i contenuti sono:

John: quaranta: 21-5821-0

+1

Come fai a sapere che si chiama due volte? Controllato nel debugger? Hai due voci nel vettore? Se l'ultimo, entrambe le voci sono le stesse? –

+1

+1, ha avuto lo stesso problema di recente ... per qualche ragione, l'incremento iteratore nel codice 'copia' stava causando la lettura, piuttosto che il dereferenziamento, quindi esegue una lettura di troppo. Detto questo, l'operatore '' deve controllare lo stato dopo le prime due operazioni 'getline'! –

+0

È inutile preoccuparsi del codice I/O che non controlla i valori di ritorno. È necessario * sempre * controllare i valori di ritorno delle operazioni di I/O. –

risposta

3

In generale, leggere in un intero file, si legge fino a quando una lettura non riesce. Allora sai che qualcosa è andato storto o li hai tutti. In ogni caso, non puoi sapere di aver raggiunto la fine del file finché non riesci a leggere. Dal momento che il primo riesce, deve provare una seconda volta, per scoprire se c'è un secondo elemento. Lo psudocode per questo è

while(in_stream >> object) { 
    myvector.push_back(object); 
} 

Si noti inoltre che questo è il modo "idiomatico" di leggere un intero file di valori. Se stai verificando la disponibilità di eof, fail o bad, probabilmente il codice è sbagliato.

Detto questo, la tua funzione istream& operator>>(istream& is, user& s) va bene. La seconda volta che viene chiamato, il primo getline avrà esito negativo, impostando il flusso su uno stato non valido (eof), i successivi due getline avranno esito negativo, e restituirà il flusso, e tutto funziona perfettamente. Ricorda solo che alcune o tutte quelle variabili possono contenere assurdità complete, dal momento che la lettura non è andata a buon fine.

Problemi correlati