Страницы

Поиск по вопросам

суббота, 7 марта 2020 г.

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

#cpp #файлы #app


Доброго дня. По заданию требуется записать в бинарник несколько массивов структур. 
Как я делал: передаю массив и размер в функцию, считываю из файла первые четыре байта(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();
}


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


Ответы

Ответ 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+");

Ответ 2



Вам нужен соответствующий флаг при открытии файла, попробуйте так: std::ifstream file(name, std::ios::binary | std::ios::app);

Комментариев нет:

Отправить комментарий