2012-10-15 3 views
5

Dopo aver letto una riga da un file usando ifstream, c'è un modo per riportare lo stream all'inizio della riga che ho appena letto, condizionatamente?Come restituire un ifstream indietro all'inizio di una riga che è stata appena letta in C++?

using namespace std; 
//Some code here 
ifstream ifs(filename); 
string line; 
while(ifs >> line) 
{ 
    //Some code here related to the line I just read 

    if(someCondition == true) 
    { 
    //Go back to the beginning of the line just read 
    } 
    //More code here 
} 

Quindi, se someCondition è vero, la prossima linea di leggere durante il prossimo ciclo while iterazione sarà la stessa linea che ho appena letto in questo momento. In caso contrario, la successiva iterazione ciclo while utilizzerà la seguente riga nel file. Se hai bisogno di ulteriori chiarimenti, non esitare a chiedere. Grazie in anticipo!

UPDATE # 1

Così ho provato quanto segue:

while(ifs >> line) 
{ 
    //Some code here related to the line I just read 
    int place = ifs.tellg(); 
    if(someCondition == true) 
    { 
    //Go back to the beginning of the line just read 
    ifs.seekg(place); 
    } 
    //More code here 
} 

Ma non legge più la stessa linea quando la condizione è vera. Un numero intero è un tipo accettabile qui?

UPDATE # 2: La soluzione

C'è stato un errore nella mia logica. Ecco la versione corretta che funziona come voglio che per nessuno di coloro che sono curiosi:

int place = 0; 
while(ifs >> line) 
{ 
    //Some code here related to the line I just read 

    if(someCondition == true) 
    { 
    //Go back to the beginning of the line just read 
    ifs.seekg(place); 
    } 
    place = ifs.tellg(); 
    //More code here 
} 

La chiamata a tellg() è stato spostato alla fine perché è necessario cercare l'inizio della prima lettura linea. La prima volta ho chiamato tellg() e ho chiamato seekg() prima che il flusso fosse cambiato, motivo per cui sembrava che nulla fosse cambiato (perché in realtà non lo era). Grazie a tutti per aver contribuito.

+1

Utilizzare tellg() per ottenere la posizione dello stream prima di leggere la riga e seekg() per impostare la posizione dello stream sulla posizione precedentemente salvata. –

+1

A proposito, ifs >> to string non sta ottenendo linee, ma parole. Usa std :: getline –

+0

Grazie per quanto riguarda getline. Potrebbe aver causato fastidiosi bug in futuro. –

risposta

3

Non v'è alcun modo diretto per dire "tornare al punto di partenza dell'ultima riga". Tuttavia, è possibile tornare a una posizione mantenuta utilizzando std::istream::tellg(). Cioè, prima di leggere una riga devi usare tellg() e poi seekg() per tornare alla posizione.

Tuttavia, chiamare frequentemente le funzioni di ricerca è piuttosto costoso, cioè, vorrei esaminare la rimozione del requisito di leggere nuovamente le righe.

+0

Grazie. L'efficienza non è la mia preoccupazione immediata, ma cercherò di esaminare altri modi per farlo in seguito. In questo momento il mio obiettivo principale è solo quello di ottenere qualcosa che funzioni. –

+0

Ho bisogno di leggere caratteri da un file 40gb in una funzione fino a quando non colpisco un carattere (caratteri delimitatore) che la funzione non dovrebbe leggere. Sta usando peek() meno costoso o tellg() seekg() per segnare la posizione del carattere precedente, a cui devo tornare? Immagino che il più efficiente sarebbe non usare nulla di tutto ciò e solo restituire il carattere di lettura extra. – bkarj

+0

@BehroozKarjoo: usare 'peek()' è abbastanza economico. In sostanza restituisce this-> gptr()! = This-> egptr()? * this-> gptr(): this-> underflow(); '(espande correttamente il' char' in un 'int', sebbene). Supponendo che il flusso sia bufferizzato, si tratta di un confronto tra puntatore e dereferenziazione. Una chiamata 'peek()' fa molto più lavoro. –