C:如何从文件中加载列表并在程序结束时保存

C:如何从文件中加载列表并在程序结束时保存,c,list,struct,save,C,List,Struct,Save,我正在研究两个函数。第一个将列表从文件加载到程序中(在开始时),第二个将列表的数据保存到文件中。我曾试图编写这两个函数,但我遇到了困难(我不太擅长编程)。下面是我正在使用的结构,我还添加了索引的定义和列表的创建: #define index 30 typedef struct dataR* data; struct dataR{ int age; char name[index]; }; typedef struct nodeR* n

我正在研究两个函数。第一个将列表从文件加载到程序中(在开始时),第二个将列表的数据保存到文件中。我曾试图编写这两个函数,但我遇到了困难(我不太擅长编程)。下面是我正在使用的结构,我还添加了索引的定义和列表的创建:

#define index 30

typedef struct dataR* data;
    struct dataR{
        int age;
        char name[index];

    };

    typedef struct nodeR* node;
    struct nodeR{
        data a;
        node next;

    };

    typedef struct listR* list;
    struct listR{
        node head, tail, curr; 
        int size;
    };

list list_create(){
    list List=malloc(sizeof(struct listR));
    assert(List);
    List->head=NULL;
    List->tail=NULL;
    List->curr=NULL;
    List->size=0;
    return List;
}
以下是将文件数据加载到列表中的函数(在程序开始时)。显然这是错误的,但我不知道如何将数据加载到每个节点,因为列表是空的:

    list load(char *filename, list List)
    {
       FILE *fd=fopen("filename","r");
       fscanf(fd, "%d",&(List->head->a->age));
       fscanf(fd, "%s",&(List->head->a->name[index-1]));
       fclose(fd);
       fd=NULL;
    }
以下是在程序结束时保存列表所有数据的函数:

    void save(char *filename, list List)
    {
       FILE *fd=fopen("filename.dat","w");
       if (fd==NULL)
       {
          printf("File does not exist");
          return;
       }
       fwrite(List->head->a, sizeof(struct dataR),1,fd);
       node tmp=List->head->next;
       while(tmp->next!=NULL)
       {
          fwrite(tmp->next->a, sizeof(struct dataR),1,fd);
          tmp=tmp->next;
       }

       fclose(fd);
       fd=NULL;
    }
文件中的数据应如下所示:

35 Nick
29 Jim
19 Helen
当然,函数并不是这样做的。所以我需要一些帮助来改进它们。非常感谢您提供的任何提示(关于文件)和帮助。我很抱歉发了这么长的帖子。谢谢你抽出时间

像这样修复

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define S_(v) #v
#define S(v) S_(v) //stringify

#define MAX_NAME_LENGTH 30 //index is bad name

typedef struct dataR* data;
struct dataR{
    int age;
    char name[MAX_NAME_LENGTH + 1];
};

typedef struct nodeR* node;
struct nodeR{
    data a;
    node next;
};

typedef struct listR* list;
struct listR{
    node head, tail, curr;//curr unused?
    int size;
};

list list_create(void){
    list List = malloc(sizeof(*List));
    assert(List);
    List->curr = List->tail = List->head = NULL;
    List->size=0;
    return List;
}

void addList(list List, data new_data){
    node new_node = malloc(sizeof(*new_node));
    new_node->a = new_data;
    new_node->next = NULL;
    if(List->head == NULL)
        List->head = List->tail = new_node;
    else
        List->tail = List->tail->next = new_node;
    ++List->size;
}

list load(const char *filename, list List){
    FILE *fd = fopen(filename,"r");//"filename"--> filename, LOL
    if(!fd){
        fprintf(stderr, "%s can't open in load.\n", filename);
        perror("fopen");
        return NULL;
    }
    int age;
    while(EOF != fscanf(fd, "%d", &age)){// or 1 == fscanf(fd, "%d", &age)){
        data new_data = malloc(sizeof(*new_data));
        new_data->age = age;
        fscanf(fd, "%" S(MAX_NAME_LENGTH) "s", new_data->name);
        addList(List, new_data);
    }
    fclose(fd);
    //fd=NULL;//meaningless
    return List;//need return value;
}

void save(const char *filename, list List){
    FILE *fd=fopen(filename, "w");
    if(!fd){
        fprintf(stderr, "%s can't open in save.\n", filename);
        perror("fopen");
        return ;
    }
    //fwrite(List->head->a, sizeof(struct dataR),1,fd);//fwrite doesn't match load
    node tmp = List->head;
    while(tmp){
        fprintf(fd, "%d %s\n", tmp->a->age, tmp->a->name);
        tmp = tmp->next;
    }
    fclose(fd);
}

int main(void){
    list List = list_create();

    load("list.txt", List);
    printf("List hold %d data.\n", List->size);
    data addData = malloc(sizeof(*addData));
    addData->age = 73;
    strcpy(addData->name, "Ken");
    addList(List, addData);
    save("list.txt", List);
    //deallocate
    return 0;
}
#包括
#包括
#包括
#包括
#定义S_v(v)#v
#定义S(v)S_v(v)//字符串化
#定义最大名称长度30//索引是坏名称
类型定义结构数据*数据;
结构数据{
智力年龄;
字符名称[最大名称长度+1];
};
类型定义结构节点*节点;
结构节点器{
数据a;
节点下一步;
};
类型定义结构列表*列表;
结构列表器{
节点头、尾、curr;//curr未使用?
整数大小;
};
列表创建(无效){
列表=malloc(sizeof(*list));
断言(列表);
列表->当前=列表->尾部=列表->头部=空;
列表->大小=0;
退货清单;
}
无效添加列表(列表列表、数据新\u数据){
node new_node=malloc(sizeof(*new_node));
新建_节点->a=新建_数据;
新建节点->下一步=空;
如果(列表->标题==NULL)
列表->头部=列表->尾部=新节点;
其他的
列表->尾部=列表->尾部->下一步=新建_节点;
++列表->大小;
}
列表加载(常量字符*文件名,列表列表){
FILE*fd=fopen(文件名,“r”);/“文件名”-->文件名,LOL
如果(!fd){
fprintf(stderr,“%s无法在加载时打开。\n”,文件名);
佩罗尔(“福彭”);
返回NULL;
}
智力年龄;
而(EOF!=fscanf(fd,“%d”,&age)){//或1==fscanf(fd,“%d”,&age)){
数据新数据=malloc(sizeof(*新数据));
新数据->年龄=年龄;
fscanf(fd,“%”S(最大名称长度)“S”,新数据->名称;
addList(列表、新的_数据);
}
fclose(fd);
//fd=NULL;//无意义
返回列表;//需要返回值;
}
无效保存(常量字符*文件名,列表){
FILE*fd=fopen(文件名,“w”);
如果(!fd){
fprintf(stderr,“%s无法在保存中打开。\n”,文件名);
佩罗尔(“福彭”);
返回;
}
//fwrite(List->head->a,sizeof(struct dataR),1,fd);//fwrite与加载不匹配
节点tmp=列表->头部;
while(tmp){
fprintf(fd,“%d%s\n”,tmp->a->age,tmp->a->name);
tmp=tmp->next;
}
fclose(fd);
}
内部主(空){
list list=list_create();
加载(“list.txt”,list);
printf(“列表保存%d个数据。\n”,列表->大小);
data addData=malloc(sizeof(*addData));
addData->age=73;
strcpy(addData->name,“Ken”);
addList(List,addData);
保存(“list.txt”,list);
//解除分配
返回0;
}

您需要问一个特定的问题(“我需要帮助”不具体)。似乎您的加载和保存都是错误的。因此,请一次只关注其中一个,并就此提出一个特定的问题。您从未为列表或其元素分配任何内存。@kaylum我应该更改什么?这是我的问题。我认为主题是特定的。这个问题来自于发布代码的相关部分,或者是整个代码(如果有)不太长,请声明代码使用的所有变量。另外,请注意:关闭上一个问题,选择其中一个答案…加载函数使用
fscanf
,因此保存函数应该使用
fprintf
非常感谢您的时间。您的帖子非常有用。祝您愉快,身体健康。