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

如何用文件读取的数字创建链表?fgets能否生成完整链表?

问题分析与修正方案

首先明确:你的当前代码既不会生成完整链表,也不会正确填充第一个节点,存在多个关键问题,下面逐一拆解并给出修正方案:

核心问题点

  • fgets使用完全错误:seq1是Nodo*类型的链表节点指针,fgets是用于读取字符串到字符数组的函数,直接将节点指针传给fgets会导致内存越界、类型不匹配,完全无法正确读取数字。
  • 仅创建了单个节点:你只malloc了一个seq1和seq2节点,循环中没有动态创建新节点的逻辑,根本无法构建多节点的链表。
  • feof循环条件错误:用!feof(f1)作为循环条件会导致最后一次读取失败后仍进入循环,引发错误。
  • 参数冗余且被覆盖:函数参数中的f1、f2被函数内的fopen重新赋值,完全没有利用传入的参数,属于无效设计。
  • 未完成数字转换:文件中是数字文本,需要用atoi或sscanf将读取的字符串转为int,存入节点的dato字段。

修正后的代码示例

以下是能正确从文件读取数字并构建链表的代码:

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

// 提前定义类型,避免函数声明报错
typedef FILE* fp;

typedef struct Nd {
    int dato;
    struct Nd* next;
} Nodo;

typedef Nodo* lista;

// 辅助函数:创建新节点
lista creaNodo(int num) {
    lista nuovo = (lista)malloc(sizeof(Nodo));
    if (nuovo == NULL) {
        printf("Errore allocazione memoria\n");
        exit(1);
    }
    nuovo->dato = num;
    nuovo->next = NULL;
    return nuovo;
}

// 辅助函数:尾插节点到链表
void aggiungiInCoda(lista* testa, lista nuovo) {
    if (*testa == NULL) {
        *testa = nuovo;
        return;
    }
    lista corrente = *testa;
    while (corrente->next != NULL) {
        corrente = corrente->next;
    }
    corrente->next = nuovo;
}

int Sequenza() {
    lista seq1 = NULL, seq2 = NULL;
    fp f1, f2;
    char buffer[256]; // 用字符数组存读取的每行字符串
    int num;

    f1 = fopen("sequenza1.txt", "r");
    f2 = fopen("sequenza2.txt", "r");

    if (f1 == NULL || f2 == NULL) {
        printf("Errore nell'apertura di uno dei due file\n");
        return 0;
    }

    // 读取第一个文件构建链表seq1
    while (fgets(buffer, sizeof(buffer), f1) != NULL) {
        // 去除换行符
        buffer[strcspn(buffer, "\n")] = '\0';
        num = atoi(buffer); // 转成int
        lista nuovo = creaNodo(num);
        aggiungiInCoda(&seq1, nuovo);
    }

    // 读取第二个文件构建链表seq2
    while (fgets(buffer, sizeof(buffer), f2) != NULL) {
        buffer[strcspn(buffer, "\n")] = '\0';
        num = atoi(buffer);
        lista nuovo = creaNodo(num);
        aggiungiInCoda(&seq2, nuovo);
    }

    // 示例:打印seq1验证结果
    printf("Sequenza 1: ");
    lista corrente = seq1;
    while (corrente != NULL) {
        printf("%d ", corrente->dato);
        corrente = corrente->next;
    }
    printf("\n");

    // 记得用完链表后释放内存(可自行补充释放逻辑)

    fclose(f1);
    fclose(f2);
    return 1;
}

// 主函数测试
int main() {
    Sequenza();
    return 0;
}

关键修正说明

  • 用字符数组接收文件内容:先用fgets读取每行字符串到buffer,再转换为int类型,避免类型错误。
  • 动态创建节点:每读取一个数字就调用creaNodo创建新节点,完美解决未知节点数量的问题。
  • 尾插法构建链表:通过aggiungiInCoda函数将新节点添加到链表尾部,保证链表的连续性。
  • 正确的循环条件:用fgets != NULL判断是否读取结束,避免feof的陷阱。
  • 内存安全:创建节点时检查malloc是否成功,后续可添加链表内存释放逻辑,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:00:56