C 从文件中读取链表并加载数据
我编写了一个C代码来实现一个使用链表的字典(节点按排序顺序排列)。我希望将数据保存到一个文件中,并能够在下次运行程序时重新加载数据。我无法从文件中加载数据。以下是我用于读取和写入数据的代码:C 从文件中读取链表并加载数据,c,file,struct,io,linked-list,C,File,Struct,Io,Linked List,我编写了一个C代码来实现一个使用链表的字典(节点按排序顺序排列)。我希望将数据保存到一个文件中,并能够在下次运行程序时重新加载数据。我无法从文件中加载数据。以下是我用于读取和写入数据的代码: struct node{ char word[20]; char meaning[5][100]; //2D array for saving multiple meanings of a word struct node *next; }; void ReadData(struc
struct node{
char word[20];
char meaning[5][100]; //2D array for saving multiple meanings of a word
struct node *next;
};
void ReadData(struct node *head)
{
struct node *tail;
FILE *fp = fopen("dictionary.data", "rb");
if(fp == NULL)
{
printf("Error opening file..\n");
return;
}
while(!feof(fp))
{
tail = (struct node*)calloc(1, sizeof(struct node));
fread(tail->word, sizeof(head->word), 1, fp);
fread(tail->meaning, sizeof(head->meaning), 1, fp);
if(head == NULL) //for fresh run head is initialized with NULL
{
tail->next = head;
head = tail;
}
else
{
head->next = tail;
head = head->next;
}
}
fclose(fp);
}
我无法将数据从文件加载到链接列表。代码不起作用。我想不出问题出在哪里。以下是我将数据写入文件的方式:
/*I think this code is working because size of the file increases after running the code*/
void WriteData(struct node *head)
{
FILE *fp = fopen("dictionary.data", "wb");
if(fp == NULL)
{
printf("Error opening file..\n");
return;
}
while(head != NULL)
{
fwrite(head->word, sizeof(head->word), 1, fp);
fwrite(head->meaning, sizeof(head->meaning), 1, fp);
head = head->next;
}
fclose(fp);
}
我使用了sizeof
,而不是strlen
,它是一个字符串。它的结尾将有空字符-字符串没有问题。但它会消耗更多内存。试试这个(未测试):
试试这个(未经测试):
那本书不适合阅读。。它用于将数据写入下一个节点。如果else部分用于固定节点之间的链接,则在
读取数据中fread
读取将由fread
完成。如果else
部分用于固定节点之间的链接,则在else
部分head->next=tail
中将新节点的地址分配给head
指向的节点的next
文件。现在我们必须将头部指向新节点(尾部),新节点的地址被分配给上一个节点的next
字段(head->next=tail
)。因此,为了将头部
指向新节点,我使用头部=头部->下一个
作为头部->下一个
=尾部的地址确定。。但我认为是一样的。因为head->next
持有tail
的地址,主要问题是您无法在函数中更改调用方的head
。在ReadData
中,不需要参数<应返回代码>标题。该标题不用于阅读。。它用于将数据写入下一个节点。如果else部分用于固定节点之间的链接,则在读取数据中fread
读取将由fread
完成。如果else
部分用于固定节点之间的链接,则在else
部分head->next=tail
中将新节点的地址分配给head
指向的节点的next
文件。现在我们必须将头部指向新节点(尾部),新节点的地址被分配给上一个节点的next
字段(head->next=tail
)。因此,为了将头部
指向新节点,我使用头部=头部->下一个
作为头部->下一个
=尾部的地址确定。。但我认为是一样的。因为head->next
持有tail
的地址,主要问题是您无法在函数中更改调用方的head
。在ReadData
中,不需要参数<应返回code>head。函数不能返回NULL
。如果malloc()
失败,则必须将所有指针传递到free()
,否则会出现大规模内存泄漏。@user3629249是的,我的错误是Null返回为空。谢谢你指出。我刚刚指出了当Malloc失败时列表的发布,因为它不是一个中心示例。void
函数不能返回NULL
。如果malloc()
失败,则必须将所有指针传递到free()
,否则会出现大规模内存泄漏。@user3629249是的,我的错误是Null返回为空。谢谢你指出。我只是指出了当Malloc失败时列表的发布,因为它不是一个中心示例。
void ReadData(struct node **head){//or struct node *ReadData(void){ ... return head; }
struct node temp = { .next = NULL };//{ {0}, {{0}}, NULL}
struct node *hp, *curr;
FILE *fp = fopen("dictionary.data", "rb");
if(fp == NULL){
printf("Error opening file..\n");
return;
}
hp = *head;
while(fread(temp.word, sizeof(temp.word), 1, fp) && fread(temp.meaning, sizeof(temp.meaning), 1, fp)){
struct node *np = malloc(sizeof(*np));
if(np == NULL){
perror("couldn't make new node by malloc:");
return ;//release list
}
*np = temp;
if(hp == NULL){//for fresh run head is initialized with NULL
curr = hp = np;
} else {//If *head isn't NULL, you need to move to the last node first.
curr = curr->next = np;
}
}
fclose(fp);
*head = hp;
}
//....................
int main(void){
//...
struct node *head = NULL;
//...
ReadData(&head);
//...