Недавно я узнал, что для правильного чтения из текстового файла мы используем
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
.
Пожалуйста, объясните, как мне читать из двоичного файла без чтения дополнительной записи.
В реальной программе я вообще не использую >>
.
Я просто говорю, потому что вы упомянули об этом. В любом случае, опубликуйте минимальный воспроизводимый пример, как требуется здесь, который воспроизводит вашу проблему, пожалуйста. Вы знаете, что это необходимо при публикации здесь.#
Сделаю. Спасибо!
Это то же самое, что и ваш текстовый пример, тест на file
должен быть после чтения, а не до.
for (;;)
{
obj1.read_binary(file);
if (!file) // did the previous read fail?
break; // if so quit the loop
records.push_back(obj1);
}
Если вы хотите читать двоичные данные, то извлечение в текстовом формате с использованием
>>
, вероятно, плохая идея. Вместо этого взгляните на std::istream::read().