запишете структура от данни във файл, използвайки двоичен режим

кодът изглежда така:

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...) отменя всички твърдения по-горе във ваша полза. Нещото с типа низ на c++ ще бъде ОК, ще бъде по-лесно да добавяте нови атрибути и да се интегрирате с всеки друг език. - person olivecoder; 16.08.2012

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

Това е само една употреба за използване на двоичен код, но основната причина за това е скоростта.

И за да прочетете данните обратно, ще трябва да знаете формата, в който сте ги записали, например като прост пример, ако запазя цяло число, char масив с размер n и булево, ще трябва да прочета двоичния файл файл като цяло число, char масив с размер 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 може да не е отхвърлен, но е разширен значително и всеки компилатор, за който се сещам, позволява използването и на двата. Истинският въпрос е защо да възпираме някого да използва силно оптимизиран и широко използван клас, който почти определено е достъпен за OP - 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++ Middleware Writer поддържа двоична сериализация към/от файлове.

От гледна точка на маршалинга членът "unsigned int age" на вашата структура е потенциален проблем. Бих обмислил промяна на типа на uint32_t.

person Jake    schedule 16.08.2012