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

链表有序打印异常求助:代码仅输出45的问题排查

链表仅输出最后一个元素的问题分析与修复

核心问题

你写的代码里,list函数只在循环外创建了一个节点,后续每次读取数字时,都是直接修改这个节点的数值再插入链表。这就导致所有插入操作都在复用同一个内存块——之前插入的节点会被覆盖,最终链表只剩这一个节点,值就是最后读取的45;同时反复插入同一个节点还会造成链表循环引用,彻底破坏结构。

修复方案

要解决这个问题,必须每次读取新数字时都创建一个新节点,不能复用同一个节点。另外还要注意:如果需求是按数组原始顺序打印,原代码的插入逻辑(排序插入)是错的,需要改成尾插法;如果是要排序后打印,只需要修复节点创建的问题即可。

方案1:按数组原始顺序打印(尾插法)

修改后的完整代码:

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

typedef struct node_s node_t;
struct node_s
{
    int n;
    struct node_s *next;
};

node_t *new_element()
{
    node_t *new_node;
    new_node = malloc(sizeof(node_t));
    if(new_node == NULL)
    {
        printf("Memory allocation failed");
        exit(1);
    }
    return new_node;
}

node_t *list(node_t *head)
{
    FILE *file;
    file = fopen("file", "r");
    if(file == NULL)
    {
        perror("Failed to open file");
        exit(1);
    }
    int n;
    node_t *new_node = NULL;
    node_t *tail = head;

    while (fscanf(file, "%d", &n) != EOF)
    {
        new_node = new_element(); // 每次循环创建新节点
        new_node->n = n;
        new_node->next = NULL;

        if(head == NULL)
        {
            head = new_node;
            tail = head;
        }
        else
        {
            tail->next = new_node;
            tail = new_node;
        }
    }
    fclose(file); // 关闭文件,避免资源泄漏
    return head;
}

void printList(node_t *head)
{
    node_t *curr = head;
    while(curr != NULL)
    {
        printf("%d-->", curr->n);
        curr = curr->next;
    }
    printf("NULL");
    return;
}

int main() {
    node_t *head = NULL;
    head = list(head);
    printList(head);
    return 0;
}

方案2:按升序排序后打印

如果你的需求是排序后输出,只需要把创建节点的代码移到循环内,保留原插入逻辑即可:

// 仅修改list函数,其余函数与上方一致
node_t *list(node_t *head)
{
    FILE *file;
    file = fopen("file", "r");
    if(file == NULL)
    {
        perror("Failed to open file");
        exit(1);
    }
    int n;
    node_t *new_node = NULL;
    node_t *p = NULL;

    while (fscanf(file, "%d", &n) != EOF)
    {
        new_node = new_element(); // 每次创建新节点
        new_node->n = n;
        new_node->next = NULL;

        if(head == NULL)
        {
            head = new_node;
        }
        else
        {
            p = head;
            while (p->next != NULL && p->next->n < new_node->n)
            {
                p = p->next;
            }
            new_node->next = p->next;
            p->next = new_node;
        }
    }
    fclose(file);
    return head;
}

额外注意事项

  • 原代码未关闭文件,会造成资源泄漏,修复时添加了fclose(file)。
  • new是C语言的关键字,建议不要用它做变量名(改成new_node或curr),避免编译问题。
  • 用perror替代直接打印"Error",能更清晰地显示文件打开失败的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:07:19