Domanda

Il codice seguente, quando compilato ed eseguito con g ++, stampa "1" due volte, mentre mi aspetto che venga stampato "1" solo una volta, dal momento che sto scaricando un'unica struttura a il file, ma durante la lettura sembra essere leggere due strutture. Perché?

#include <iostream.h>
#include <fstream.h>

int main(){
    struct student
    {
        int rollNo;
    };
    struct student stud1;
    stud1.rollNo = 1;

    ofstream fout;
    fout.open("stu1.dat");
    fout.write((char*)&stud1,sizeof(stud1));
    fout.close();

    ifstream filin("stu1.dat");
    struct student tmpStu;
    while(!filin.eof())
    {
          filin.read((char*)&tmpStu,sizeof(tmpStu));
      cout << tmpStu.rollNo << endl; 
    }
    filin.close();
}
È stato utile?

Soluzione

eof viene impostato solo dopo una lettura non riuscita, quindi la lettura viene eseguita due volte e la seconda volta non modifica il buffer.

Prova questo:

while(filin.read((char*)&tmpStu,sizeof(tmpStu)))
{
    cout << tmpStu.rollNo << endl; 
}

O

while(!filin.read((char*)&tmpStu,sizeof(tmpStu)).eof())
{
    cout << tmpStu.rollNo << endl; 
}

Leggi restituisce un riferimento a filin quando viene chiamato, che valuterà vero se lo stream è ancora buono. Quando read non riesce a leggere altri dati, il riferimento verrà valutato come falso, impedendogli di entrare nel ciclo.

Altri suggerimenti

Il ciclo while viene eseguito due volte perché la condizione EOF non è vera fino al primo tentativo di leggere oltre la fine del file. Quindi il cout viene eseguito due volte.

Stampa 1 due volte a causa del modo esatto in cui funzionano eof e read . Se sei alla fine di un file, read fallirà, quindi le chiamate a eof dopo che torneranno vere. Se non hai tentato di leggere oltre la fine del file, eof restituirà false perché il flusso non è nello stato EOF, anche se non ci sono più dati da leggere.

Per riassumere, le tue chiamate sono così:

eof - false (at beginning of file)
read (at beginning of file)
eof - false (now at end of file, but EOF not set)
read (at end of file. fails and sets EOF state internally)
eof - true (EOF state set)

Una strategia migliore sarebbe quella di controllare eof subito dopo la chiamata read .

Credo che sia perché stai controllando filin.eof () e questo non sarà vero fino alla seconda lettura.

Vedi qui . Nota che è impostato eofbit " ... La fine della fonte di caratteri viene raggiunta prima che n caratteri siano stati letti ... " ;. Nel tuo caso non colpirai EOF fino alla seconda lettura.

Cool. Un altro modo (per gentile concessione dello scambio di esperti, ho fatto la stessa domanda lì :-))

while(filin.peek() != EOF)
{
    filin.read((char*)&tmpStu,sizeof(tmpStu));
    cout << tmpStu.rollNo << endl;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top