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

код выглядит так:

struct Dog {
  string name;
  unsigned int age;
};

int main()
{
    Dog d = {.age = 3, .name = "Lion"};
    FILE *fp = fopen("dog.txt", "wb");
    fwrite(&d, sizeof(d), 1, fp);   //write d into dog.txt
}

Моя проблема в том, какой смысл записывать объект данных или структуру в двоичный файл? Я предполагаю, что это для того, чтобы сделать данные, сгенерированные в работающей программе, постоянными, верно? Если да, то как мне вернуть данные? Используете fread?

Это заставляет меня думать о вещах, подобных базам данных, доза базы данных записывает данные на диск таким же образом?


person Alcott    schedule 16.08.2012    source источник
comment
Вы действительно говорите о C? Что такое тип строки?   -  person olivecoder    schedule 16.08.2012


Ответы (4)


Вы можете сделать это, но у вас будет много проблем, о которых нужно позаботиться:

  • типы структур: все ваши данные должны на самом деле быть в структуре, или вы можете просто написать указатель на какое-то другое место.
  • изменения структуры: если вам нужно изменить свою структуру, вам нужно будет написать конвертер для чтения старой структуры и записи новой.
  • языковая совместимость: будет сложно получить доступ к данным, используя другой язык

Это было обычной практикой в ​​первые дни до популяризации реляционных баз данных. Вы можете создавать индексные файлы, указывающие на номер записи.

Однако в настоящее время я советую вам сделать сериализацию и писать строки вместо двоичных файлов.

ПРИМЕЧАНИЕ: если строка похожа на char[40], ваш код, возможно, выживет... но если ваш вопрос касается C++, а строка является классом, то убей своего ребенка, прежде чем он вырастет! Символы строкового объекта находятся не в вашей структуре, а в куче.

person olivecoder    schedule 16.08.2012
comment
Зачем писать строки вместо двоичных? - person Alcott; 16.08.2012
comment
Запись строк в формате с фиксированным размером (csv,Jason,XML...) отменяет все приведенные выше утверждения в вашу пользу. Со строковым типом С++ все будет в порядке, будет проще добавлять новые атрибуты и интегрировать с любым другим языком. - person olivecoder; 16.08.2012

Запись данных в двоичном формате чрезвычайно полезна и намного быстрее, чем чтение/запись в тексте, например видеоигры (хотя не каждая видеоигра делает это), когда игра сохраняется, все необходимые структуры/классы и другие данные записываются в файл сохранения в двоичном формате.

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

И чтобы прочитать данные обратно, вам нужно будет знать формат, в котором вы их сохранили, например, в качестве простого примера, если бы я сохранил целое число, массив символов размера n и логическое значение, мне нужно было бы прочитать двоичный файл файл в виде целого числа, массива символов размера n и логического значения. В противном случае данные считываются некорректно и вообще не будут очень полезны.

person user1294021    schedule 16.08.2012
comment
Также я бы подумал об использовании класса C++ fstream, так как он намного проще в использовании и избавляет от многих головных болей. - person user1294021; 16.08.2012
comment
Чем полезен fstream, если вы используете C? - person Adrian Cornish; 16.08.2012
comment
Он пометил его как C, но есть строковый тип, который делает его похожим на C++. - person Scooter; 16.08.2012
comment
Вот почему я указал C++... верно? Нет причин НЕ использовать C++ так же, как и C, C может и не считаться устаревшим, но он был значительно расширен, и каждый компилятор, о котором я могу думать, позволяет использовать оба. Реальный вопрос заключается в том, зачем удерживать кого-то от использования высокооптимизированного и широко используемого класса, который почти наверняка доступен для ОП. - person user1294021; 16.08.2012
comment
Почему это быстрее, чем в текстовом режиме? - person Alcott; 16.08.2012
comment
это быстрее, потому что избегайте преобразования типов и используйте меньше байтов. - person olivecoder; 16.08.2012
comment
Двоичный всегда быстрее, чем чтение текста, а также, если вы сохраняете свои целые числа в виде текстовой строки, вам нужно преобразовать эту строку в целое число, которое очень медленно, если вы используете двоичный файл, вы можете напрямую прочитать двоичный файл в целое число . - person user1294021; 17.08.2012

Будь осторожен. Тип поля «имя» в вашей структуре — «строка». Этот класс содержит данные, выделяемые динамически. Таким образом, при записи «строковых» данных в файл будут записываться только указатели, а не сами данные.

person Danil Onishchenko    schedule 16.08.2012
comment
правильно, если вы используете класс строки C++, вам нужно будет использовать string.c_str() для извлечения строки char и использовать string.size() * sizeof(char) для размера строки. - person user1294021; 16.08.2012
comment
Тогда как мне записать данные name в файл? fwrite(name.c_str(), name.size(), 1, fp)?\ - person Alcott; 16.08.2012
comment
В этом случае вы также должны записать длину строки в файл. Вместо этого вы не можете прочитать это правильно. Или вы можете написать '\0' в конец строки. - person Danil Onishchenko; 16.08.2012
comment
Точно, нужно либо нулевое завершение, либо заголовок, содержащий размер. - person user1294021; 17.08.2012

программа записи промежуточного программного обеспечения C++ поддерживает двоичную сериализацию в/из файлов.

С точки зрения сортировки элемент "unsigned int age" вашей структуры является потенциальной проблемой. Я бы подумал об изменении типа на uint32_t.

person Jake    schedule 16.08.2012