2009-01-13 4 views
2

После кода, при компиляции и работать с г ++, печатает «1» в два раза, в то время как я ожидаю, «1», чтобы напечатать только один раз, так как я демпинг единую структуру для файловой , но при чтении, кажется, чтение двух структур. Зачем?C++ обработки файлов (структуры)

#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(); 
} 

ответ

11

eof только получает набор после чтения не удается, так что чтение выполняется дважды, и второй раз, он не изменяет буфер.

Попробуйте это:

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

Или

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

Read возвращает ссылку на Филин при вызове, которая будет оценивать истинное значение, если поток по-прежнему хорошо. Когда чтение не считывает больше данных, эта ссылка будет оцениваться как ложная, что не позволит ей войти в цикл.

5

Ваш цикл while выполняется дважды, потому что условие EOF не является истинным до первой попытки прочитать за пределами файла. Таким образом, cout выполняется дважды.

1

Я считаю, что это потому, что вы проверяете filin.eof(), и это будет неверно до второго раза, когда вы читаете.

См. here. Он отмечает, что eofbit установлен «... Конец источника символов достигнут до того, как n символов были прочитаны ...». В вашем случае вы не будете ударять EOF до второго чтения.

2

Это печатает 1 дважды из-за точного способа eof и read работы. Если вы находитесь в самом конце файла, read не сработает, затем звонит eofпосле этого return true. Если вы не пытались прочитать за конец файла, eof вернет false, потому что поток не находится в состоянии EOF, даже если больше нет данных для чтения.

Итак, ваши звонки выглядеть следующим образом:

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) 

Лучшей стратегией было бы проверить eof сразу после read вызова.

0

Прохладный. Другой способ (любезно предоставлен экспертами-биржей, я задал тот же вопрос там :-))

while(filin.peek() != EOF) 
{ 
    filin.read((char*)&tmpStu,sizeof(tmpStu)); 
    cout << tmpStu.rollNo << endl; 
} 
Смежные вопросы