Как я могу сохранить структуру в файл .... C lang - PullRequest
7 голосов
/ 30 июля 2009

Я хотел бы сохранить структуру в файле. Я хотел бы реализовать функцию, которая делает эту работу. Я пробовал этот код, но он не работал.

struct utilisateur   // enregestrement pour sauvegarder les details de l utilisateur
{
 char nom[20];
 char prenom[20];
 int place;
 char depart[20];
 char arrive[20];
 char sexe;
 int nwagon;
};

struct utilisateur utilis;
struct utilisateur *Table[48];

void crea_fich(struct utilisateur *Tutilis)
// creation un fichier, vous introduiez le nom, et le sotcker par enreg
{
    FILE *f;
    if (f!==0)
    {
         printf("error in the name of file \n");
         exit(1);
    }
    if (f=fopen(futilis,"w")==Null){
         fprint("We can't creat file \n");
         exit(1);
    }
    else{
        f=fopen("futilis.dat","wb");
        fwrite(Tutilis ,sizeof(utilisateur),1,f);
    }
}

Ответы [ 6 ]

6 голосов
/ 30 июля 2009

Майкл С прав; использование fwrite со структурой крайне непереносимо. Но давайте предположим, что вас это не волнует, и вы хотите написать что-нибудь простое, что сработает.

Проблема в вашем коде в том, что вы нарушили золотое правило sizeof: никогда не используйте sizeof с именем типа . Вместо этого вы должны использовать sizeof с lvalue и почти всегда с разыменованием другого аргумента . Таким образом

Tutilis = malloc (sizeof (*Tutilis));
  ...
fwrite(Tutilis, sizeof (*Tutilis), 1, f);

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

6 голосов
/ 30 июля 2009

Попробуйте это, и затем, если это не делает то, что вы хотите, попробуйте объяснить, чем это отличается от того, что вы хотите.

void crea_fich(struct utilisateur *Tutilis)
{
   FILE *f;
   size_t nwritten;

   f = fopen("futilis.dat","wb");

   if (f == NULL)
   {
      fprintf(stderr, "Cannot open file for writing.\n");
      exit(1);
   }

   nwritten = fwrite(Tutilis, sizeof Tutilis[0], 1, f);
   fclose(f);

   if (nwritten < 1)
   {
      fprintf(stderr, "Writing to file failed.\n");
      exit(1);
   }
}
6 голосов
/ 30 июля 2009

Просто простой пример:)

// your struct
struct Data
{
    int first;
    double second;
    char third[10];
};

Тогда напишите структуру!

struct Data data = {22, 4.0, "Hi"};
FILE* output;

output = fopen("Data.dat", "wb");

fwrite(&data, sizeof(data), 1, output);

fclose(output);

Наконец прочитайте данные из файла, который вы создали!

struct Data data;
FILE* input;

input = fopen("Data.dat", "rb");

fread(&data, sizeof(data), 1, input);

// you got the data from the file!

fclose(input);

Двоичные файлы - это кошмары, если их не писать и читать с умом. Вы должны позаботиться о многих вещах об архитектуре, где был создан файл и где он будет прочитан. Порядок и размер переменных являются наиболее важными. Кроме того, если у вас есть указатели внутри struct, указатель, который будет записан в файл, а не фактические данные, на которые указывает указатель. Извините, я не редактировал ваш код, потому что он полон ошибок компиляции:)

Я удалил свой первый ответ, потому что это было так неправильно, извините:)

6 голосов
/ 30 июля 2009

Нет. Вы должны выписать свои данные индивидуально, по одному за раз. Вы не должны просто слепо копировать представление памяти вашей структуры в буфер вывода файла (что, очевидно, вы пытаетесь сделать). Таким образом, запись файлов приведет к тому, что файлы будут непереносимыми (они не будут доступны для чтения, кроме как на той платформе, на которой они были написаны), из-за порядка байтов и специфического для платформы заполнения элементов структуры.

1 голос
/ 28 августа 2012

Я понимаю, что это старый пост, но он появляется, когда люди ищут эту информацию, поэтому я дам свое собственное решение.

Это в основном то, что я использовал в одной из моих игр. На самом деле у меня есть некоторый дополнительный специфичный для библиотеки код в моей собственной функции для диалогов, но это по сути дела. Я пишу данные индивидуально. Я не думаю, что у меня есть структура для этих данных, но нет никакой разницы, просто напишите ваши отдельные члены структуры отдельно. Как уже упоминалось, так лучше.

// returns 1 if successful, 0 if not
int savemap(const char *map_name)
{
   FILE *file = NULL;

   // open the file in write binary mode
   file = fopen(map_name, "wb");

   // always check return values to see if it was opened okay
   if(file == NULL) {
      fprintf(stderr, "Error opening file for writing.\n");
      return 0;
   }

   // write file ID, version and pills
   fwrite(MAP_ID, sizeof(char), strlen(MAP_ID)+1, file);
   fwrite(&MAP_VER, sizeof(unsigned char), 1, file);
   fwrite(&pills, sizeof(unsigned short), 1, file);

   // write the map data (unsigned int map[315])
   fwrite(&map, sizeof(unsigned int), 315, file);

   // never forget to close the file
   fclose(file);

   return 1;
}
0 голосов
/ 30 июля 2009

Сначала я посмотрю на имена символов, например, NULL и fprint, не говоря уже о том, что странно \0. В качестве дополнительной мысли вы должны закрыть файл после записи, чтобы убедиться, что он записан на диск, и дважды проверить, что переменная futilis является char*, которая содержит допустимый путь для записи.

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