@armadillo-cld

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

Всем привет.
Есть такой код:
// Объявляю структуру
struct Settings {
int year;
char name[52];
};
..
long int filesize = 92672; // Приходиться контролировать размер файла =(
Settings s;
int fize = MAX_PATH;
char *filename = new char[size];
GetModuleFileNameA(NULL, filename, size); // Получаю путь к себе

ifstream file(filename, ios::binary);
file.seekg(filesize); // Ставлю указатель на конец файла
file.read((char*)&data, sizeof(Settings)); // Читаю внедрённую структуру
file.close(); // Закрываю

Это сам бинарный файл.
А вот файл, который внедряет структуру:
// Объявляю структуру 
struct Settings {
int year;
char name[52];
}
..
// Инициализирую переменные
Settings s;
s.year = 12;
strcpy(s.name, "Alesha");

// Внедряю
ifstream binaryfile("person.exe", ios::binary);
ofstream injected("person created.exe", ios::binary);

injected << binaryfile.stdbuf();
binaryfile.close();

injected.write((char*)&s, sizeof(Settings));
injected.close();


Но в этом методе есть минусы:
1. Приходиться вводить размер файла в байтах, а если ввести большие данные - размер файла станет больше введённого и будет выводиться мусор.
2. Не рабочий. Почему-то если я добавляю новых переменных. Например "char car[52];" и т.п, то выводиться либо пустые строки, либо мусор в виде *!@(EU.

Что делать? Есть какой то "кроссплатформенный" способ? Нужно перенести данные в бинарный файл как-то.
  • Вопрос задан
  • 354 просмотра
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Начнём с 2. Структуры, используемые как формат файла, применяй в прикладном коде с большой осторожностью. Если хочешь, чтобы формат расширялся, придумай простенький блочный формат.
Для 1 — приходится использовать какую-то сигнатуру и находить её в файле.
Например: после собственно EXE-файла идут данные, потом сигнатура и положение данных в файле. Сигнатуры нет или смещение странное — значит, просто приклеивай всю эту дрянь в конец файла. Сигнатура есть и смещение правдоподобное — идём по указанному смещению, пишем новые данные вместе с новой сигнатурой, а потом усекаем файл (на случай, если старые данные были длиннее).
На этом принципе, кстати, основаны самоизвлекающиеся архивы RAR и RARJPEG — только сигнатура в начале, а не в конце RAR-данных.
Ещё нужно проверить, в какой кодировке ifstream принимает данные — UTF-8 или Win-1251. Начиная с Си++17 появилась поддержка юникодных имён файлов, но я с нею не работал.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы