从c中的文件加载列表
我无法正确指定列表的结尾。我不知道为什么,但我认为这是因为从c中的文件加载列表,c,list,file,C,List,File,我无法正确指定列表的结尾。我不知道为什么,但我认为这是因为while循环的条件是允许节点从内存中获取数据,然后使其next=NULL。我试图替换node->next=NULL带有节点=NULL但它不起作用。我将非常高兴收到一些有用的解决方案或提示,并提前向您表示感谢 #include <stdio.h> #include <stdlib.h> #include <malloc.h> //my variables typedef struct { ch
while
循环的条件是允许节点从内存中获取数据,然后使其next=NULL
。我试图替换node->next=NULL代码>带有节点=NULL代码>但它不起作用。我将非常高兴收到一些有用的解决方案或提示,并提前向您表示感谢
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
//my variables
typedef struct {
char Fname[len];
char Lname[len];
double salary;
} employee;
// list of employees
typedef struct list {
employee e;
struct list *next;
} list;
void LOAD_LIST(FILE *f, list *head)
{
list *node = (list *)malloc(sizeof(list));
node = head;
while (fscanf(f, "%10s%10s%lf", node->e.Fname, node->e.Lname, &node->e.salary) != EOF)
{
node->next = (list *)malloc(sizeof(list));
if (node->next == NULL)
{
printf("memory allocation failed\n");
break;
}
node = node->next;
}
node->next = NULL;
}
void DISPLAY(list *node)
{
while (node != NULL)
{
printf("%s | %s | %.2lf\n", node->e.Fname, node->e.Lname, node->e.salary);
node = node->next;
}
}
void freeList(struct list *head)
{
list *tmp;
while (head != NULL)
{
tmp = head;
head = head->next;
free(tmp);
}
}
int main()
{
FILE *file = fopen("file.txt", "r");
list *listhead = (list *)malloc(sizeof(listhead));
LOAD_LIST(file, listhead);
DISPLAY(listhead);
freeList(listhead);
fclose(file);
return 0;
}
我认为您的代码中存在一些问题:
您总是在main()
中分配链表的标题,如果您的文件是空的,并且没有通过文件解析数据,该怎么办。我认为您应该修改LOAD\u LIST
方法以返回新的列表头
在LOAD_LIST
方法的while
循环中,在使用fscanf
读取之前分配LIST*节点。这意味着无论在fscanf期间发生什么,都会分配一个额外的节点。我认为您应该在阅读后通过fscanf
分配内存,检查解析的字符数是否等于3
不确定原因,但您正在读取节点的内容时分配节点->下一个的内存。如果这是您正在读取的文件的最后一行呢。最后会有一个额外的节点
我将节点内存分配+初始化逻辑移动到方法createNewNode
,并跟踪head
和prevNode
变量,以跟踪链接列表的开始和最后分配的节点:
list*createNewNode(char firstName[],char lastName[],双薪){
list*newNode=(list*)malloc(sizeof(list));
if(newNode==NULL){
printf(“节点内存分配失败\n”);
返回NULL;
}
strcpy(newNode->e.fName,firstName);
strcpy(newNode->e.lName,lastName);
newNode->e.salary=salary;
newNode->next=NULL;
}
列表*加载列表(文件*f)
{
列表*head=NULL,*prevNode=NULL;
char firstName[100],lastName[100];
双薪;
而(fscanf(f,“%10s%10s%lf”、名、姓和薪水)==3){
list*currentNode=createNewNode(名字、姓氏、薪水);
if(currentNode==NULL){
printf(“内存分配失败\n”);
打破
}
if(head==NULL){
head=当前节点;
prevNode=currentNode;
}否则{
prevNode->next=currentNode;
prevNode=currentNode;
}
}
回流头;
}
// ...
int main(){
FILE*FILE=fopen(“FILE.txt”、“r”);
列表*列表头=加载列表(文件);
显示器(列表头);
自由列表(列表头);
fclose(文件);
返回0;
}
我使用如下文件进行了测试:
Rohan Kumar 100
Robert Dicosta 200
Rupert Griffin 30
BadInput
这将提供以下输出:
c-posts : $ ./a.out
Rohan | Kumar | 100.00
Robert | Dicosta | 200.00
Rupert | Griffin | 30.00
node=malloc(…)代码>后跟节点=头部
是内存泄漏:您丢失了malloced内存。在main
中,您不会初始化刚刚分配的listhead
。您应该检查fscanf
是否读取了正确数量的参数,即3。您附加了一个节点,然后读取了它的数据。如果读取失败,则必须删除此节点。注意:ALLCAPS
名称通常是为C中的常量和宏保留的。不需要强制转换malloc
的返回,这是不必要的。请参阅:。您不需要在main()
中为listfead
分配,只需声明指针并将其地址传递到LOAD\u LIST()
并更新地址即可<代码>节点=头部代码>覆盖您刚才分配的内存块的地址,造成内存泄漏。感谢您的努力这实际上很有帮助,但我试图做的是尽量少使用变量,因为我认为太多变量会使代码在执行时变得混乱和缓慢。。。ofc在这种情况下,速度是不明显的,但如果它是一个长期的项目,它会影响我的节目质量吗?我的意思是使用更少的变量,同时保持它的可理解性好还是不好?哦,如果你想减少变量的使用,你可能想先分配内存,使用fscanf读取并释放fscanf失败的情况我介绍的大多数变量都是函数范围变量,每当控件移出函数时,这些变量就会被销毁。读取的局部变量是正确的方法。没有必要分配,直到你知道你有一个成功的阅读。。。
c-posts : $ ./a.out
Rohan | Kumar | 100.00
Robert | Dicosta | 200.00
Rupert | Griffin | 30.00