You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言从文件读取创建链表时最后一行重复读取问题求助

解决读取文件创建链表时最后一行重复的问题

嘿,这个坑我之前也踩过!核心问题出在你用while(!feof(fp))作为循环条件——feof()的逻辑是只有当你尝试读取超过文件末尾之后,才会触发文件结束标记。所以当你读完最后一行有效数据时,feof(fp)还是false,会再跑一次循环。这时候fscanf读取失败,但你还是执行了打印和内存分配操作,导致最后一行的旧数据被重复输出(其实是上一次的内容没被覆盖,因为这次读取没成功)。

给你几个关键修改点,彻底解决这个问题:

1. 用fscanf的返回值替代feof作为循环条件

fscanf会返回成功读取的参数个数,我们要读取name、id、marks三个参数,所以当返回值等于3时,才说明读取到了有效数据。直接用这个作为循环判断条件,就能精准控制循环次数。

2. 修复链表结尾,避免空节点

原代码每次创建节点都直接分配下一个节点,会导致链表最后多一个空节点,记得把最后一个节点的next设为NULL,符合链表规范。

3. 补上原代码的其他小漏洞

比如没检查文件是否成功打开、没关闭文件、struct定义末尾少分号、void main不符合C标准等,这些细节也容易引发问题。

下面是修改后的完整代码:

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

struct student {
    int id;
    char name[20];
    float marks;
    struct student *next; // 补上缺失的分号
};
typedef struct student node;

int main() { // 改用int main符合C标准规范
    node *head = NULL;
    void read(node *p);
    void print(node *p);
    int count(node *p);

    head = (node *)malloc(sizeof(node));
    if(head == NULL) { // 检查内存分配是否成功
        printf("Memory allocation failed!\n");
        return 1;
    }
    read(head);

    // 可调用print函数验证链表输出
    // print(head);

    return 0;
}

void read(node *list) {
    FILE *fp;
    char filename[30];
    int read_result;

    printf("input file name:");
    scanf("%s", filename);

    fp = fopen(filename, "r");
    if(fp == NULL) { // 检查文件是否成功打开
        printf("Failed to open file!\n");
        return;
    }

    // 先读取第一组数据
    read_result = fscanf(fp, "%s %d %f", list->name, &list->id, &list->marks);
    while(read_result == 3) {
        printf("%s \t%d \t%f\n", list->name, list->id, list->marks);
        // 分配下一个节点并检查内存
        list->next = (node*)malloc(sizeof(node));
        if(list->next == NULL) {
            printf("Memory allocation failed!\n");
            fclose(fp);
            return;
        }
        list = list->next;
        // 读取下一组数据
        read_result = fscanf(fp, "%s %d %f", list->name, &list->id, &list->marks);
    }
    // 最后一个节点的next设为NULL,结束链表
    list->next = NULL;
    fclose(fp); // 关闭文件释放资源
}

// 可保留你的print、count函数,此处省略

这样修改后,就不会再重复读取最后一行了,同时也修复了几个潜在的bug。

内容的提问来源于stack exchange,提问作者ThisIsHard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:03:45