Чтение дублированных объектов в файлах C ++ - PullRequest
0 голосов
/ 10 апреля 2020

У меня проблемы с созданием файловой системы для моей программы на C ++. Ну, я создаю нового студента, и, если он является последним объектом, который я создаю перед сохранением файлов и закрытием программы, он дублируется. Например, два объекта: Даниил, Пол . Он показывает только последний дубликат: Даниэль, Пол , Пол - в файле file.txt.

Вот мой код:

ЧТЕНИЕ ФАЙЛА:

ifstream file;
file.open("file.txt");

while (1)
{
Student *p = new Student();
    if (file.eof() || file.bad() || file.fail())
    {
        break;
    }

    getline(file, ALLTHESTRINGVARIABLES);
    p->STRINGVARIABLES = ALLTHESTRINGVARIABLES;

    file >> ANOTHERVARIABLES;
    p->NOTSTRINGVARIABLES = ANOTHERVARIABLES;

    students.push_back(p);
}
file.close();

ПИСЬМО ФАЙЛА:

   fstream file;
   file.open("file.txt", ios::out | ios::trunc);
      for(unsigned int i = 0; i < students.size(); i++){
         file << students[i]->VARIABLEEXAMPLE << endl;
      }
   file.close();

Спасибо !!

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

eof() не вернет true до тех пор, пока вы на самом деле не попытаетесь прочитать за пределами файла, поэтому вы видите, что последняя строка дублирована. getline не удастся, а ALLTHESTRINGVARIABLES будет содержать значения из последнего успешного чтения. Вместо этого вы должны проверить, действительно ли извлечение завершилось успешно, перед сохранением нового Student.

Поскольку вы смешиваете неформатированный и отформатированный ввод, вы также должны удалить символ новой строки (или любой другой символ, который вы используете для разделения записей) из stream.

Измените l oop на:

if (std::ifstream file("file.txt"); file)
{
    while (std::getline(file, ALLTHESTRINGVARIABLES) >> ANOTHERVARIABLES)
    {
        // remove the newline or whatever whitespace char you use as record separator
        file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

        Student *p = new Student;
        p->STRINGVARIABLES = ALLTHESTRINGVARIABLES;
        p->NOTSTRINGVARIABLES = ANOTHERVARIABLES;
        students.push_back(p);
    }
}

Я также предлагаю не хранить указатели (если вы не используете динамическую c диспетчеризацию), а вместо этого сохранять фактические Student объекты в std::vector<Student>. Если используется динамическая отправка c, сохраните std::unique_ptr<Student> в vector.

1 голос
/ 10 апреля 2020

eof (), bad (), fail () вернет true только после попытки прочитать некоторые байты из файла без успеха. Итак, поместите проверку if после getline ().

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

Вот так:

while (1)
{
    getline(file, ALLTHESTRINGVARIABLES);
    if (file.eof() || file.bad() || file.fail())
        break;

    Student *p = new Student();
    p->STRINGVARIABLES = ALLTHESTRINGVARIABLES;

    file >> ANOTHERVARIABLES;
    p->NOTSTRINGVARIABLES = ANOTHERVARIABLES;

    students.push_back(p);
}
...