Сохранение структуры в файл - PullRequest
3 голосов
/ 26 сентября 2010

Я хочу сохранить многомерный массив в файл. Структура например:

struct StructSub {
    unsigned short id;
};
struct MyStruct {
    struct StructSub sub[3];
};

// Use the struct
struct MyStruct main;
int i = 0;
while (i < 3) {
    main.sub[i].id = i;
    i++;
}

Для этого примера я хочу сохранить данные в файл в следующем формате (обычный текст):

MyStruct main {
    StructSub sub[0] {
        id = 0;
    }
    StructSub sub[1] {
        id = 1;
    }
    StructSub sub[2] {
        id = 2;
    }
}

Какой самый простой способ сделать это?

Ответы [ 6 ]

6 голосов
/ 26 сентября 2010

Помните, что сохранение необработанных структур в файл, подобный этому, вообще не переносимо. Компилятор может добавить заполнение в структуру (изменение sizeof (your_struct)), порядковый номер может отличаться и т. Д. Если это не имеет значения, то fwrite () работает нормально.

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

3 голосов
/ 26 сентября 2010

Попробуйте это

struct StructSub {
    unsigned short id;
};
struct MyStruct {
    struct StructSub sub[10];
};

// Use the struct
struct MyStruct main;
int i = 0;
while (i < 10) {
    main.sub[i].id = i;
}

Запись в файл

FILE* output;
output = fopen("Data.dat", "wb");
fwrite(&main, sizeof(main), 1, output);
fclose(output);

Чтение файла

struct Data data;
FILE* input;
input = fopen("Data.dat", "rb");
fread(&main, sizeof(main), 1, input);
// you got the data from the file!
fclose(input);

этиподдержка ссылок, о чем весь код выше - http://c -faq.com / struct / io.html

fwrite(&somestruct, sizeof somestruct, 1, fp);
2 голосов
/ 26 сентября 2010

Полагаю, что-то вроде этого - больше, чем вы хотите.Это не так кратко, как могло бы быть, но это очень просто и может быть легко расширено, чтобы приспособить другие структуры.

void WriteIndent(FILE* file, int indent) {
    int i = 0;
    while (i < indent) {
        fprintf(file, "\t");
        ++i;
    }
}


void WriteStructSub(FILE* file, StructSub* s, char* id, int indent) {

    WriteIndent(file, indent);
    fprintf(file, "StructSub %s {\n", id);

    WriteIndent(file, indent + 1);
    fprintf(file, "id = %i;\n", s->id);

    WriteIndent(file, indent);
    fprintf(file, "}\n");

}


void WriteMyStruct(FILE* file, MyStruct* s, char* id, int indent) {

    WriteIndent(file, indent);
    fprintf(file, "MyStruct %s {\n", id);
    int i = 0;

    while (i < 3) {

        char name[7];
        sprintf(name, "sub[%i]", i);

        WriteStructSub(file, &s->sub[i], name, indent + 1);
        ++i;

    }

    WriteIndent(file, indent);
    fprintf(file, "}\n");

}


int main(int argc, char** argv) {

    MyStruct s;
    int i = 0;
    while (i < 3) {
        s.sub[i].id = i;
        ++i;
    }

    FILE* output = fopen("data.out", "w");
    WriteMyStruct(output, &s, "main", 0);
    fclose(output);

}
2 голосов
/ 26 сентября 2010

Вы можете использовать библиотеки Serialization , которые делают это.

Если вы можете использовать C ++, для этого есть библиотека Boost :: Serialization .Вы также можете оформить заказ:

  1. s11n библиотека.
  2. Этот ответ .
  3. Tpl библиотека.
1 голос
/ 26 сентября 2010

Помимо названия объекта main, которое может вызвать у вас множество странных проблем: просто перебор - это не лучший способ

/* pseudo code */
write struct header
foreach element
    write element header
    write element value(s)
    write element footer
endfor
write struct footer
1 голос
/ 26 сентября 2010

вы можете использовать базовый fileio, просто убедитесь, что вы пишете в двоичном .

FILE * pFile;
pFile = fopen( "structs.bin","wb" );
if ( pFile!=NULL ) {
  frwite( main, 1, sizeof(struct MyStruct), pFile );
  fclose (pFile);
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...