将一个结构体读取/写入二进制文件

8

我正在运行一个包含3个结构体的程序,我所做的是读/写二进制文件,具体操作如下:

struct Medico
{
    int Id_Doctor;
    int Estado;
    char Nombre[60];
    char Clave_Acceso[20];
    char Especialidad[40]; 
    struct Medico *next;
};

typedef struct Medico *Medicazos;
typedef struct Medico Meds;

Medicazos Nuevo;
FILE *Archivaldo;
char especialida[40], password[20];
char nombre_doc[60];
int estado_doc, id_doc;

Archivaldo=fopen("md.dat", "rb");
fclose(Archivaldo);

if((Archivaldo=fopen("md.dat", "rb"))==NULL)
{
    printf("No se pudo abrir el archivo de Medicos\n"); //couldnt open file msg
    exit(1);
}

rewind(Archivaldo);
while(!feof(Archivaldo))
{
    if(*Inicio != NULL)  //read from file and write in struct
    {
        Nuevo = (Medicazos) malloc (sizeof(Meds)); //new=pointer
        fread(&id_doc, sizeof(int), 1, Archivaldo);
        fread(nombre_doc, sizeof(char), sizeof(nombre_doc), Archivaldo);
        fread(password, sizeof(char), 20 , Archivaldo);
        fread(especialida, sizeof(char), 40, Archivaldo);
        fread(&estado_doc, sizeof(int), 1, Archivaldo);
        Nuevo->Id_Doctor=id_doc; ///copies data in structure
        strcpy(Nuevo -> Nombre , nombre_doc);
        strcpy(Nuevo -> Clave_Acceso, password);
        strcpy(Nuevo -> Especialidad, especialida);
        Nuevo-> Estado = estado_doc;
        printf("---------------------------------\n"); //display info
        printf("ID: %d\n", id_doc);
        printf("\nDoctor: ");
        puts(nombre_doc);
        printf("\nPassword: ");
        puts(password);
        printf("\nEspecialidad: ");
        puts(especialida);
        printf("\nEstado: ");
        if(estado_doc==1)
            puts("Activo\n");
        else
            puts("Inactivo\n");
        Nuevo-> next = *Inicio;
        *Inicio = Nuevo;
     }
     else 
     {
         *Inicio = (Medicazos)malloc(sizeof(Meds));
         fread(&id_doc, sizeof(int), 1, Archivaldo);
         fread(nombre_doc, sizeof(char), sizeof(nombre_doc), Archivaldo);
         fread(password, sizeof(char), 20 , Archivaldo);
         fread(especialida, sizeof(char), 40, Archivaldo);
         fread(&estado_doc, sizeof(int), 1, Archivaldo);
         (*Inicio)->Id_Doctor=id_doc;
         strcpy((*Inicio) -> Nombre , nombre_doc);
         strcpy((*Inicio) -> Clave_Acceso, password);
         strcpy((*Inicio) -> Especialidad, especialida);
         (*Inicio)-> Estado = estado_doc;
         printf("--------------------------------\n"); //display info
         printf("ID: %d\n", id_doc);
         printf("\nDoctor: ");
         puts(nombre_doc);
         printf("\nPassword: ");
         puts(password);
         printf("\nEspecialidad: ");
         puts(especialida);
         printf("\nEstado: ");
         if(estado_doc==1)
             puts("Activo\n");
         else
             puts("Inactivo\n");
         (*Inicio) -> next = NULL;
     }
 }
 fclose(Archivaldo);

有没有简化这个的方法?

编辑: 还有,当我尝试显示文件时,有人告诉我不要在读取/写入时使用feof。我不记得为什么了。可以用什么替代它呢?


1
请在以后标记您的问题所使用的编程语言。我已经将其标记为C,因为看起来您只使用了C语言。 - wkl
我以为我做了,非常抱歉;顺便说一下,每次我似乎在发布问题时格式化代码,但它似乎没有格式化。 - drodri420
为什么不将你的结构序列化成类似json的格式,并将其存储在磁盘上作为文本文件(而不是二进制文件)?这样做会使调试更简单,而且文本文件通常比二进制文件更易于管理。 - Noufal Ibrahim
我非常想在txt文件上执行此操作,但是我需要在二进制文件上执行。 - drodri420
1个回答

46

我假设你的结构体长这样:

struct Medicazos
{
  char Nombre[60];
  char Clave_Acceso[20];
  char Especialidad[40];
  int Id_Doctor;
  int Estado;
}

你可以将这个人作为一个单元来读取/写入/复制。在你真正使用这些值之前,没有必要进行分块访问。

struct Medicazos m = {"Bob", "Password", "Feet", 123, 456};

FILE* f = fopen(...);
fwrite(&m, sizeof(struct Medicazos), 1, f);

对于 fread,同样的情况(但是是反向的)也是成立的。

(顺便提一句,你的变量名全部大写让我难以忍受。)


18
+1 对于你的干净回答,我希望我能再给你一个+1,因为你最后一条评论提到了变量名。 - Noufal Ibrahim
1
我假设这段代码没有考虑字节序的影响? - GWW
2
@GWW 不会比原问题更多。 - Ryan Calhoun
3
@GWW 我也不是。字面上来看,将5个fread读取到5个结构体字段中或将1个fread读取到整个结构体中,字节序对结果没有影响。C结构体和数组一样,总是按升序排列字节顺序。字符字符串则不受影响。如果从大端机器传输到小端机器,则需要反转两个整数的字节(但不与彼此交换)。 - Ryan Calhoun
2
@ozanmuyes 最簡短的答案是,如果結構中有指針,則無法應用此答案。指針存儲內存地址,如果將其寫入文件,然後再從文件讀取,那麼它們就沒有意義了。 - Ryan Calhoun
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接