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

使用链表读取打印文件内容时出现无限输出乱码问题求助

问题分析与修复

你的代码出现「打印第一个单词后无限输出随机符号」的核心原因是结构体内存分配错误,另外还有几个次要问题需要修正:

核心错误:结构体内存分配不足

在创建节点时,你写了:

tmp=malloc(sizeof(node*));

这里分配的是node*指针的大小(通常为4或8字节),但node结构体包含一个char*和一个node*成员,实际需要分配整个结构体的内存空间。正确写法应该是:

tmp=malloc(sizeof(node));

内存分配不足会导致tmp->next的内存区域未被正确初始化,变成野指针,遍历链表时无法正常终止,进而出现无限循环和随机垃圾值。

其他需要修正的问题

  1. 冗余的函数参数:createlist函数的FILE *file参数完全没用,函数内部自己打开了文件,main里传入的是未初始化的指针,直接删掉这个参数即可。
  2. 未关闭文件:打开文件后没有调用fclose,会导致资源泄漏。
  3. 内存泄漏:程序结束前没有释放链表节点和字符串的内存,长期运行会浪费系统资源,建议添加销毁链表的函数。
  4. 读取逻辑可选调整:fscanf("%s", buffer)是按单个单词读取(空格/换行作为分隔符),如果你的需求是读取整行内容,应该改用fgets。

修复后的完整代码

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

#define N 100

typedef struct node
{
    char *str;
    struct node* next;
} node;

node *createlist()
{
    node *tmp=NULL;
    node *head=NULL;
    node* p=NULL;
    char buffer[N+3];

    FILE *file=fopen("file","r");
    if(file==NULL)
    {
        printf("Error opening file\n");
        exit(1);
    }
    // 如果要读取整行,替换下面的fscanf为fgets:
    // while(fgets(buffer, N+3, file) != NULL)
    while(fscanf(file,"%s",buffer)!=EOF)
    {
        // 修复:分配结构体大小而非指针大小
        tmp=malloc(sizeof(node));
        if(tmp==NULL)
        {
            printf("Allocation error\n");
            exit(1);
        }
        tmp->str=malloc((strlen(buffer)+1)*sizeof(char));
        if(tmp->str == NULL)
        {
            printf("Allocation error\n");
            exit(2);
        }
        tmp->next=NULL;
        strcpy(tmp->str,buffer);
        
        if(head==NULL)
        {
            head=tmp;
        }
        else
        {
            p=head;
            while(p->next !=NULL)
            {
                p=p->next;
            }
            p->next=tmp;
        }
    }
    fclose(file); // 关闭文件
    return head;
}

void printfile(node *head)
{
    node* tmp=head;
    while(tmp != NULL)
    {
        printf("%s ",tmp->str);
        tmp=tmp->next;
    }
    printf("\n");
}

// 添加销毁链表的函数,避免内存泄漏
void freelist(node *head)
{
    node *tmp;
    while(head != NULL)
    {
        tmp=head;
        head=head->next;
        free(tmp->str);
        free(tmp);
    }
}

int main()
{
    node *head=NULL;

    head=createlist();
    printfile(head);
    freelist(head); // 释放内存

    return 0;
}

额外说明

如果你的需求是读取文件的每一行(而不是每个单词),把createlist里的fscanf替换为fgets即可,同时可以去掉换行符:

while(fgets(buffer, N+3, file) != NULL)
{
    // 去掉换行符
    buffer[strcspn(buffer, "\n")] = '\0';
    // 后续节点创建代码不变
}

内容的提问来源于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.25 08:57:50