C 为什么我的;“打印”;函数只读取最后一个元素和垃圾,然后停止响应?
看起来它打印了最后一行和下一行(这是垃圾)。我想问题出在read函数中 这是正确的 原因如下:C 为什么我的;“打印”;函数只读取最后一个元素和垃圾,然后停止响应?,c,linked-list,C,Linked List,看起来它打印了最后一行和下一行(这是垃圾)。我想问题出在read函数中 这是正确的 原因如下: input file name: input.txt.txt student01 1 95.000000 student03 3 90.000000 student05 5 86.000000 student07 7 83.000000 student09 9 98.000000 s
input file name: input.txt.txt
student01 1 95.000000
student03 3 90.000000
student05 5 86.000000
student07 7 83.000000
student09 9 98.000000
student10 10 93.000000
student08 8 92.000000
student06 6 96.000000
student04 4 93.000000
student02 2 88.000000
ID=2
Name=student02
Marks=88.000000
ID=11552328
░ame=P
Marks=13640062821560266000000000000000000.000000
Process returned -1073741819 (0xC0000005) execution time : 6.737 s
Press any key to continue.
在这个循环中,您总是读取列表第一个元素中的所有数据。
您分配了一些新节点,但从未向其分配任何内容。
通过将NULL
赋值给list->next->next
,您甚至不会终止列表
这导致了各种问题:
- 您可以为每个迭代分配内存,但只能通过
访问最后一个迭代。所有其他内存块都将丢失list->next
- 您有一个未终止的列表,当您在打印期间尝试遍历所有节点时,该列表会导致未定义的行为
- 您将所有数据读取到一个位置,这意味着您丢失了文件中除最后一行以外的所有数据
while(fscanf(fp, "%s %d %f", list->name, &list->id, &list->marks) == 3)
{
printf("%s \t%d \t%f\n", list->name,list->id,list->marks);//check
list->next=(node*)malloc(sizeof(node));//create next node
}
除此之外:
- 显然,您没有使用
可能具有main
返回类型的嵌入式系统。对于所有托管环境,它必须返回void
int
- 为什么定义标准宏
?您应该包括定义它的C标准标题。除此之外,NULL
是一个指针值。为什么使用整数类型NULL
while(fscanf(fp, "%s %d %f", list->name, &list->id, &list->marks) == 3)
{
printf("%s \t%d \t%f\n", list->name,list->id,list->marks);//check
list->next=(node*)malloc(sizeof(node));//create next node
if (list->next != NULL)
{
list = list->next; // Advance to new node
list->next = NULL; // Terminate list at this node (until a new one is added)
}
else
{
// error handling
exit(1);
}
}
struct student
next
字段free()
head
的地址正确地传递给read()
函数,因此当列表为空时,可以使用指向第一个节点的指针更新head
的内容
头
指针正确初始化为NULL while(fscanf(fp, "%s %d %f", list->name, &list->id, &list->marks) == 3)
{
printf("%s \t%d \t%f\n", list->name,list->id,list->marks);//check
list->next=(node*)malloc(sizeof(node));//create next node
if (list->next != NULL)
{
list = list->next; // Advance to new node
list->next = NULL; // Terminate list at this node (until a new one is added)
}
else
{
// error handling
exit(1);
}
}
#包括//文件、fopen、fclose、scanf()、fscanf()、printf()
#包括//malloc()、free()、exit()、exit_失败
#include//memcpy()
#定义最大名称长度20
#定义最大文件名长度30
结构学生
{
int-id;
字符名[MAX_name_LEN];
浮标;
结构学生*下一步;
};
typedef结构学生节点;
无效读取回波记录(节点**p);
void创建(节点*p);
整数计数(节点*p);
作废打印(节点*p);
内部主(空)
{
node*head=NULL;
读取回音记录(&head);
printf(“\n”);
打印头;
}
作废读取\回显\记录(节点**列表)
{
文件*fp;
字符文件名[MAX_filename_LEN];
printf(“输入文件名:”);
scanf(“%29s”,文件名);
fp=fopen(文件名,“r”);
如果(fp==NULL)
{
perror(“fopen失败”);
退出(退出失败);
}
节点*当前=*列表;
节点*prior=*列表;
节点工作空间;
workspace.next=NULL;
而(fscanf(fp,“%s%d%f”,workspace.name,&workspace.id,&workspace.marks)==3)
{
printf(“%s\t%d\t%f\n”,workspace.name,workspace.id,workspace.marks);//检查
if(!(current=malloc(sizeof(node)))//创建下一个节点
{
perror(“malloc失败”);
fclose(fp);
退出(退出失败);
}
memcpy(当前和工作空间,大小(节点));
*上一个->下一个=当前;
先验=当前;
}
fclose(fp);
返回;
}
作废打印(节点*列表)
{
节点*当前=列表;
如果(!当前)
{
printf(“%s\n”,“列表为空”);
返回;
}
while(当前->下一步)
{
printf(“ID=%d\n”,当前->ID);
printf(“名称=%s\n”,当前->名称);
printf(“标记=%f\n”,当前->标记);
printf(“\n”);
当前=当前->下一步;
}
}
我没有将数据分配给节点,你能解释一下吗?你分配了一个指针list->next
,但从未给分配内存的任何字段分配任何值。我不确定这里有什么不清楚的地方…或者这样说:你认为,你在哪里使用那个新节点?对不起,我真的是个新手。我想你的意思是我总是读取文件并在第一个节点分配它,而不是分配到下一个节点?是的,正确。您没有切换到新的/下一个节点。关于:#定义NULL 0
这不是有效的NULL定义。有效的定义是#define NULL void*0
发布的代码不编译!它缺少printf()
和fopen()
和scanf()
和fscanf()
的原型,以及NULL和FILE
和fclose()
所有这些都可以通过包含头文件来更正:stdio.h
关于语句:void main()
main()只有两个有效的签名:int main(void)
和int main(int argc,char*argv[])
注意,它们的返回类型都是int
,而不是void
函数名read()
是众所周知的函数。在struct student
的定义中,试图用“自产”函数替换C库函数的定义是一种糟糕的编程实践,此字段:struct student*next
无效,因为它缺少所需的尾随半色代码>
#include <stdlib.h> // FILE, fopen, fclose, scanf(), fscanf(), printf()
#include <stdio.h> // malloc(), free(), exit(), EXIT_FAILURE
#include <string.h> // memcpy()
#define MAX_NAME_LEN 20
#define MAX_FILENAME_LEN 30
struct student
{
int id;
char name[ MAX_NAME_LEN ];
float marks;
struct student *next;
};
typedef struct student node;
void read_echo_records (node **p);
void create(node *p);
int count (node *p);
void print (node *p);
int main( void )
{
node *head = NULL;
read_echo_records( &head);
printf("\n");
print(head);
}
void read_echo_records(node **list)
{
FILE *fp;
char filename[ MAX_FILENAME_LEN ];
printf("input file name: ");
scanf("%29s",filename);
fp = fopen( filename, "r" );
if( fp == NULL )
{
perror( "fopen failed" );
exit( EXIT_FAILURE );
}
node *current = *list;
node *prior = *list;
node workspace;
workspace.next = NULL;
while(fscanf(fp, "%s %d %f", workspace.name, &workspace.id, &workspace.marks) == 3)
{
printf("%s \t%d \t%f\n", workspace.name, workspace.id, workspace.marks);//check
if( ! (current = malloc(sizeof(node))) )//create next node
{
perror( "malloc failed" );
fclose( fp );
exit( EXIT_FAILURE );
}
memcpy( current, &workspace, sizeof( node ) );
*prior->next = current;
prior = current;
}
fclose(fp);
return;
}
void print(node*list)
{
node *current = list;
if( ! current )
{
printf( "%s\n", "list is empty" );
return;
}
while( current->next )
{
printf( "ID=%d\n", current->id );
printf( "Name=%s\n", current->name );
printf( "Marks=%f\n", current->marks );
printf( "\n");
current = current->next;
}
}