#c #binary #ofstream
#c #двоичный #ofstream
Вопрос:
Для небольшого формата файла, который я разрабатываю, мне нужно вывести заголовок размером 519 байт в файл. Я немного новичок во всей концепции ofstream. Хотя у меня есть некоторый опыт чтения заголовка файла Targa Truevision. Но вывод — это то, с чем я далеко не знаком.
Итак, в основном, вот моя проблема.
Я открыл экземпляр ofstream, и мне нужно вывести заголовок следующим образом:
typedef struct header {
char version; // offset 0, length 1
short int width; // offset 1, length 2
short int height; // offset 3, length 2
short int pathlen; // offset 5, length 2
char desc[512]; // offset 7, length 512
} fileHeader;
Теперь мне нужно получить все это в первых 519 байтах файла, остальное содержимое меняется, как бы я мог скопировать этот заголовок в свой файл?
Я предпочтительно хочу сделать это с помощью класса ofstream, но я также в порядке с оригинальной библиотекой C. Я занимаюсь этим уже 2 часа, и пока ничего не добился, и попытки поиска в Google тоже не очень помогают.
Ответ №1:
std::ofstreamamp; operator<<(std::ofstreamamp; out, const headeramp; myheader) {
out.write((char*)amp;myheader.version, sizeof(myheader.version));
out.write((char*)amp;myheader.width, sizeof(myheader.width));
out.write((char*)amp;myheader.height, sizeof(myheader.height));
out.write((char*)amp;myheader.pathlen, sizeof(myheader.pathlen));
out.write((char*)amp;myheader.desc, sizeof(myheader.desc));
return out;
}
std::ifstreamamp; operator>>(std::ifstreamamp; in, headeramp; myheader) {
in.read((char*)amp;myheader.version, sizeof(myheader.version));
in.read((char*)amp;myheader.width, sizeof(myheader.width));
in.read((char*)amp;myheader.height, sizeof(myheader.height));
in.read((char*)amp;myheader.pathlen, sizeof(myheader.pathlen));
in.read((char*)amp;myheader.desc, sizeof(myheader.desc));
return in;
}
int main() {
std::cout << fileHeader << 'n';
std::cin >> fileHeader;
return 0;
}
Поскольку у вас нет указателей, это довольно просто! (Обратите внимание, что это работает только с узкими потоками)
Еще один пример, показывающий вещи с текстом и динамической памятью / указателями / etc
class thing {
std::string name;
int height;
friend std::ofstreamamp; operator<<(std::ofstreamamp; out, const thing amp; myheader);
friend std::ifstreamamp; operator>>(std::ifstreamamp; in, thing amp; myheader);
public:
thing() {}
};
std::ofstreamamp; operator<<(std::ofstreamamp; out, const thing amp; myheader) {
thing << name.size() << ' ';
thing.write(amp;name[0], name.size()) << ' ' << height;
}
std::ifstreamamp; operator>>(std::ifstreamamp; in, thing amp; myheader) {
int size;
in >> size;
myheader.name.resize(size);
in.read(amp;myheader.name[0], name.size());
return in >> myheader.height;
}
Комментарии:
1. Это приведение может привести к проблемам, если структура отформатирована неправильно.
2. Хотя я ценю ваш ответ, я хотел бы получить объяснение того, как это работает. Как я могу быть уверен, что данные записаны в правильном порядке (сначала версия, затем ширина и т. Д.). Кроме того, почему-то эта функция мне кажется неправильной. Что-то не так.
3. Вы (оба) правы, я забыл о дополнении. Ваша структура не будет занимать 519 байт в ОЗУ, только на диске. (В Windows это было бы 520 байт) Исправлено. @user1019020: они были бы в порядке, но после байта версии был бы бессмысленный байт.
4. Если вы беспокоитесь о упаковке и выравнивании слов, рекомендуется вызывать read и write для каждого элемента структуры, а не для всего сразу. Судя по вашим смещениям, вы хотите плотно упаковать данные. Ваш символ, скорее всего, дополнен короткой границей int в вашей архитектуре.
5. @MooingDuck Да, я попробовал ваш метод, а затем прочитал свой файл обратно, ширина внезапно изменилась на 5192 или что-то в этом роде, по сравнению с 20. Я попробую ваше новое предложение. 🙂