Сериализация структур

Я работаю над домашним заданием и пытаюсь сохранить данные инвентаризации в файл.

Размер данных инвентаризации не должен быть слишком большим, потому что технически никто не собирается их использовать.

Мне нужно записать это содержимое в файл:

• Описание позиции • Количество в наличии • Оптовая стоимость • Розничная стоимость • Дата добавления в запасы

Мне нужно будет сделать интерфейс, который позволит мне это сделать:

• Добавить новые записи в файл • Отобразить любую запись в файле • Изменить любую запись в файле

Struct был бы самым простым способом сделать это imo. Если бы я мог просто понять, как читать/записывать структуры в файл, это должно быть очень легко.

Если бы вы могли привести небольшой пример того, как это сделать, я был бы очень признателен.

Спасибо!


person OneShot    schedule 01.04.2009    source источник


Ответы (4)


Библиотека IOStream делает это

Класс ofstream предоставляет интерфейс для записи данных в файлы в виде выходных потоков.

Класс ifstream предоставляет интерфейс для чтения данных из файлов в качестве входных потоков.

Изменить- Пример

person TStamper    schedule 01.04.2009
comment
Я вижу, как вы можете записать структуру в файл с записью, используя ofstream. Но как бы вы прочитали это обратно? - person OneShot; 02.04.2009
comment
с ifstream... вы должны сначала использовать ifstream для чтения файла, он может быть пустым... затем записать в тот же файл - person TStamper; 02.04.2009
comment
Можете ли вы показать мне пример того, как это сделать? Просто маленький? - person OneShot; 02.04.2009
comment
Хорошая ссылка, мне очень помогла. Теперь мне просто нужно посмотреть, смогу ли я заставить этот пример, который вы предоставили, работать. - person OneShot; 02.04.2009

Спросите своего преподавателя, можете ли вы использовать библиотеку boost.
Если да, прочтите руководство по сериализации boost, оно содержит простые примеры: http://www.boost.org/doc/libs/1_38_0/libs/сериализация/doc/tutorial.html

Но если вы хотите понять, как работать с файлами, вы должны сделать это без какой-либо помощи или поддержки.

Если вы хотите работать с std::[io]fstreams, вам следует решить, какой формат вы будете поддерживать:
- текстовый - в этом случае лучше всего определить оператор‹‹ и оператор>> и использовать их для записи структуры в файл или чтения ;
- бинарный - ваша структура должна быть POD (обычные старые данные) и не должна содержать указатели - и вы будете использовать методы потоков чтения и записи.
пример для бинарного файла:
http://www.codeguru.com/forum/showthread.php?t=269648

person bayda    schedule 01.04.2009
comment
Нет, я не думаю, что он хочет, чтобы мы использовали дополнительные библиотеки. Я планирую сделать это самостоятельно, мне просто нужно понять, как читать и записывать структуры или XML в файл!!! ржунимагу - person OneShot; 02.04.2009
comment
кроме сырого дампа структуры, будет проще использовать какую-нибудь либу, чем накатывать свою. - person BCS; 02.04.2009
comment
В жизни обычно проще и лучше использовать хорошо продуманную стороннюю библиотеку, а не исследовать велосипед. Но если вы хотите понять низкий уровень - вам следует использовать std::[io]fstreams. - person bayda; 02.04.2009
comment
Хорошо, я посмотрю, что я могу сделать с ними. Я просто хочу, чтобы кто-нибудь дал мне пример того, как их использовать! - person OneShot; 02.04.2009

Если вы не возражаете против очень низкого уровня, вы можете просто скопировать структуры внутрь и наружу, приведя указатель к структуре к void* и используя sizeof() для получения длины структуры. (IIRC - это способ выгрузки/чтения пустого буфера в/из файла)


Обратите внимание, что это работает ТОЛЬКО, если данные не имеют указателей/ссылок/и т.д.


Мне нравится ввод-вывод C лучше, чем C++, поэтому:

typedef struct { int hi; int mon; char[35] dat; } S;

S s;
S arr[22];
int f;

  // write
f = open(/* I forget the args*/);

  // one
if(sizeof(s) != write(f, &s, sizeof(s))) Error();
  // many
if(sizeof(arr) != write(f, arr, sizeof(arr))) Error();

close(f);

  // read
f = open(/* I forget the args*/);

  // one
if(sizeof(s) != read(f, &s, sizeof(s))) Error();
  // many
if(sizeof(arr) != read(f, arr, sizeof(arr))) Error();

close(f);
person BCS    schedule 01.04.2009
comment
Мне ОЧЕНЬ нравится твоя идея. Не могли бы вы привести краткий пример того, как это сделать? - person OneShot; 02.04.2009
comment
@BCS: ввод-вывод ANSI / ISO C - это «fopen», «fread», «fwrite». 'open', 'read', 'write' - это POSIX/K&R C. Да, и 'open' выглядит как 'open(newfile.dat, O_CREAT | O_BINARY)' или 'open(log.txt, O_RDONLY | O_TEXT)' . - person Simon Buchan; 02.04.2009
comment
Так это просто? Что, если целочисленное значение равно 250259 вместо 2509, не изменится ли размер s, из-за чего чтение не будет работать? - person OneShot; 02.04.2009
comment
Я знаю, что открытие/чтение/запись это не материал streamIO. Если все, что вы делаете, это читаете двоичные блобы, то мне достаточно POSIX. - person BCS; 02.04.2009
comment
@OneShot: int имеет длину 32 бита, несмотря ни на что (если только это не 16 или 64 бита, но это зависит от компилятора). OTOH не ожидает чтения результирующего файла с помощью текстового редактора. - person BCS; 02.04.2009
comment
Как мне узнать, когда остановиться и прочитать следующую структуру? Этот файл сохранит несколько структур в файл. - person OneShot; 02.04.2009
comment
@Один выстрел; Вам нужно будет выяснить, в каком порядке находятся структуры во время самостоятельного чтения, но выполнение более одного чтения/записи подряд будет работать, а конец файла может быть обнаружен данным статусом if. - person BCS; 02.04.2009

Я бы пошел с XML; он структурирован, основан на тексте, поэтому вы можете просмотреть его в любом текстовом редакторе.

person Max    schedule 01.04.2009
comment
Как мне это сделать .... можете ли вы привести пример того, как я могу прочитать и правильно записать это в файл? - person OneShot; 02.04.2009