Обработка файлов C ++ (структуры) - PullRequest
2 голосов
/ 13 января 2009

Следующий код, когда компилируется и запускается с g ++, печатает '1' дважды, тогда как я ожидаю, что '1' будет напечатано только один раз, так как я сбрасываю одну структуру файл, но при чтении обратно, кажется, чтение двух структур. Почему?

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

Ответы [ 5 ]

11 голосов
/ 13 января 2009

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 возвращает ссылку на filin при вызове, которая оценивается как true, если поток все еще исправен. Если при чтении не удается прочесть больше данных, ссылка оценивается как ложная, что не позволяет ей войти в цикл.

5 голосов
/ 13 января 2009

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

2 голосов
/ 13 января 2009

Это печатает 1 дважды из-за точного способа работы eof и read. Если вы находитесь в самом конце файла, read не удастся, тогда вызовы eof после этого вернут 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.

1 голос
/ 13 января 2009

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

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

0 голосов
/ 13 января 2009

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

while(filin.peek() != EOF)
{
    filin.read((char*)&tmpStu,sizeof(tmpStu));
    cout << tmpStu.rollNo << endl;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...