Как правильно читать данные из двоичных файлов на С++ до последних данных?

Недавно я узнал, что для правильного чтения из текстового файла мы используем

while(file>>var1>>var2){
   //do stuff with data
}

вместо

while(file){
   file>>var1>>var2;
   //do stuff with data
}

потому что последний выполняет одно дополнительное чтение даже после того, как прочитан последний элемент данных, и при следующем чтении он может прочитать eof, поэтому, если у нас есть что-то вроде std::vector<CLASSNAME>CLASSVECTOR, мы получим одну дополнительную запись в векторе, а если мы используем первый метод читает только до последней записи.

Мой вопрос в том, как мне читать до последней записи в случае двоичного файла? Итак, если у меня есть что-то вроде:

class class1 {
   int a;
   class2 obj2;
   class3 obj3;
public:
   void write_ binary(std::ofstream file) const;
   void read_file(std::ifstream file);
   //rest of class definition
};

И я пишу этот класс так:

void class1::write_ binary(std::ofstream file) const {
   file.write(reinterpret_cast<const char*>(&a),sizeof(a));
   obj2.write_binary(file); //this writes the data in the same way using 
   reinterpret_cast to ofstream file
   obj3.write_binary(file); //this writes the data in the same way using 
   reinterpret_cast to ofstream file
}

А также, если я прочитаю файл так:

void class1::read_file(std::ifstream file) {
   file.read(reinterpret_cast<char*>(&a),sizeof(a));
   obj2.read_binary(file); //this reads data for obj2 in the same way using 
   read() and reinterpret_cast
   obj3.read_binary(file); //this reads data for obj3 in the same way using read() and reinterpret_cast
}

И если я хочу сохранить эти данные в векторе следующим образом:

class1 obj1;
std::vector<class1>records;

while(file)
{
   obj1.read_binary(file);
   records.push_back(obj1);
   //reset obj1 to initial state
}

В итоге я получаю дополнительную запись в vector records. Я не могу использовать while(file>>obj1), так как хочу использовать >> вместо cin. Пожалуйста, объясните, как мне читать из двоичного файла без чтения дополнительной записи.

Если вы хотите читать двоичные данные, то извлечение в текстовом формате с использованием >>, вероятно, плохая идея. Вместо этого взгляните на std::istream::read().

πάντα ῥεῖ 12.12.2020 21:59

В реальной программе я вообще не использую >>.

Pratap Biswakarma 12.12.2020 22:04

Я просто говорю, потому что вы упомянули об этом. В любом случае, опубликуйте минимальный воспроизводимый пример, как требуется здесь, который воспроизводит вашу проблему, пожалуйста. Вы знаете, что это необходимо при публикации здесь.#

πάντα ῥεῖ 12.12.2020 22:05

Сделаю. Спасибо!

Pratap Biswakarma 12.12.2020 22:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
399
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это то же самое, что и ваш текстовый пример, тест на file должен быть после чтения, а не до.

for (;;)
{
     obj1.read_binary(file);
     if (!file) // did the previous read fail?
         break; // if so quit the loop
     records.push_back(obj1);
}

Другие вопросы по теме