Запись в бинарный файл структуры

325
10 мая 2017, 09:45

Доброго дня. По заданию требуется записать в бинарник несколько массивов структур. Как я делал: передаю массив и размер в функцию, считываю из файла первые четыре байта(int), меняю размер, так как дозаписываю. Закрываю файл, открываю вновь. Записываю поверх старого размера новый размер. Затем, вновь закрываю файл, открываю вновь с дозаписью в конец(!!!), и записываю содержимое массива. Как это работает: если один раз записать массив структур и считать его обратно - то все нормально. Если дозаписать ещё один массив структур..то он не дозаписывается. Отладчиком определил, что поток для записи в конец не открывается нужным образом(функция tellp() возвращает 0, то есть курсор в самом начале файла, и писать будет сверху старого содержимого). Вот функция:

void write_file(std::string name, bank *b, int s)
{
std::ifstream file_r(name, std::ios::binary);
int tmp_size(s);
if (file_r)
{
    int size(0);
    file_r.read((char*)&size, sizeof(int));
    s += size;
    file_r.close();
}
std::ofstream file(name, std::ios::binary);
file.write((char*)&s, sizeof s);
file.close();
file.open(name, std::ios::out | std::ios::app |  std::ios::binary);  // НЕ ДОЗАПИСЫВАЕТ
int pos = file.tellp();  // файл открывается в начале 
for (int i(0); i < tmp_size; i++)
{
    int count = b[i].name.length();
    file.write((char*)(&count), sizeof(int)); // размер строки
    file.write(b[i].name.c_str(), count); // пишем строку
    file.write((char*)&b[i].num, sizeof(int));
    file.write((char*)&b[i].code, sizeof(int));
    file.write((char*)&b[i].sum, sizeof(int));
    file.write((char*)&b[i].data, sizeof(date));
}
file.close();
}

Надеюсь, я нормально преподнес информацию. Спасибо заранее.

Answer 1

Просто сразу откройте файл для записи в режиме чтение-запись и без append:

std::ofstream file;
file.open(name, std::ios::binary | std::ofstream::out | std::ofstream::in);

это предотвратит truncate файла и позволит произвольно менять его содержимое.

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

file.seekp(0, std::ios_base::end);

Однако, если файла еще нет, то его нужно создать, поэтому проще всего добавить в начало кода (перед открытием на чтение-запись) пару строк

file.open ("test.txt", std::ofstream::out | std::ofstream::app);
file.close();

А можно не морочить никому голову и открыть файл сразу создавая его, если такого еще нет в удобном для чтения-обновления-дозаписи режиме, используя POSIX:

int fd = open(name, O_RDWR | O_CREAT, 0666);
FILE *f = fdopen(fd, "r+");
Answer 2

Вам нужен соответствующий флаг при открытии файла, попробуйте так:

std::ifstream file(name, std::ios::binary | std::ios::app);
READ ALSO
Почему не создаётся файл в с++

Почему не создаётся файл в с++

Не знаю почему но не создаётся файлПисал ofstream WAVf("newWAV

338
Запись в конец файла c++

Запись в конец файла c++

Здравствуйте, я сделал запись в файл с одного класса, но нужно дописать в этот же файл результаты из второго класса, результаты накладываются...

425
Выбор класса при создании объекта

Выбор класса при создании объекта

Есть абстрактный класс К, на основе которого (наследование) созданы три других класса К1, К2, К3Создаваемый в программе объект О должен быть...

351
Ошибка модуля USB Electron JS

Ошибка модуля USB Electron JS

Uncaught Error: A dynamic link library (DLL) initialization routine failed\?\D:\JN\NODEELECTRON\node_modules\escpos\node_modules\usb\src\binding\usb_bindings

383