在void UMS_444()中,while的循环条件是p->next!=NULL。p 指向倒数第二个节点,而 p->next 是最后一个节点,可以正常进入while。之后p指向最后一个结点,最后一个结点next为NULL,不符合while的条件,按理说不会进入循环,最后一个结点的数据也无法输出。但在我的测试中,最后一个数据仍然能正常输出,求高人指点
node1* user_link()
{
node1 *head=(node1 *)malloc(sizeof(node1));
node1 *last;
head->next=NULL;
last=head;
FILE *fp;
fp=fopen("user.txt","r");
while(!feof(fp))
{
node1 *s=(node1 *)malloc(sizeof(node1));
fscanf(fp,"%d %s %d",&s->data.num,s->data.mima,&s->data.leixing);
last->next=s;
s->next=NULL;
last=s;
}
fclose(fp);
return head;
}
void UMS_444()
{
node1 *head=user_link();
node1 *p=head->next;
while(p->next!=NULL)
{
printf("%d ",p->data.num);
printf("%s ",p->data.mima);
printf("%d ",p->data.leixing);
printf("\n");
p=p->next;
}
}
在UMS_4440函数中,while循环的条件是p->next!=NULL。由于最后一个节点的next指针为NULL,因此该条件不成立,循环不会执行。但是,由于在user_link()函数中最后一个节点的next指针被设置为NULL之前已经将数据读入了内存,因此在UMS_4440函数中仍然可以访问最后一个节点的数据。
while(!feof(fp)) 这个判断会读到最后一个EOF标记后结束,
就是说你读到的最后一个数据并不是看到的最后一个数据,而是EOF,所以最后一个p指向的内容是EOF,并不是你理解的最后一个数据
参见下面的博客,搜下 feof 的解释,有很多
https://blog.csdn.net/weixin_41170125/article/details/126806010?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_utm_term~default-4-126806010-blog-94599703.235^v38^pc_relevant_anti_t3&spm=1001.2101.3001.4242.3&utm_relevant_index=7
问题分析: 这个问题可能是由于链表结构定义的问题导致的,例如最后一个节点的next可能没有置为NULL。也有可能是在循环输出的过程中,没有正确地判断循环条件,导致节点被重复输出。
解决方案: 1. 检查链表结构定义是否正确,最后一个节点的next是否被置为NULL。如果没有,可以在创建链表时手动将最后一个节点的next赋值为NULL。 2. 对于循环输出时节点被重复输出的问题,可以在循环体内加入判断条件,判断当前节点是否为最后一个节点。如果是,则跳出循环。
以下是代码示例:
typedef struct Node {
int data;
struct Node *next;
}node;
void UMS_444(node *head) {
node *p = head;
while(p->next != NULL) {
printf("%d ", p->data);
p = p->next;
if(p->next == NULL) {
printf("%d ", p->data);
break;
}
}
}
在这个示例代码中,增加了一个判断条件,如果当前节点是最后一个节点,就会跳出循环,避免了最后一个节点被重复输出的问题。