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

C语言链表排序词典文件程序无输出问题求助

问题排查与修复方案

一、核心问题分析

1. 打印函数逻辑错误

你的print_list函数循环条件完全错误,直接导致链表节点无法被正确遍历打印:

  • 原代码中while (cur->next!= NULL)会跳过最后一个节点,因为当cur指向最后一个节点时,cur->next是NULL,循环直接终止。
  • 额外的if(cur->next==NULL){return;}判断会在遍历到倒数第二个节点后直接返回,进一步导致打印不完整;如果链表只有一个节点,循环根本不会执行,完全无输出。

2. 插入函数的空指针风险

在insert函数的else分支中,while循环先执行strcmp(curr->next->word, word) < 0,但如果curr->next已经是NULL,访问curr->next->word会触发空指针解引用,可能导致程序崩溃或异常行为。你虽然写了break,但判断顺序错误,应该先检查curr->next是否存在,再做字符串比较。

3. 字符串比较逻辑不一致

插入时用了strcasecmp(忽略大小写),但后续循环用了strcmp(区分大小写),会导致排序逻辑混乱,比如大写开头的单词和小写开头的单词排序不符合预期。

4. 读取行的换行符残留

fgets会把文件中的换行符\n读入缓冲区,分割后的new_meaning可能带有换行符,导致输出时格式混乱。

二、修复后的完整代码

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

struct node 
{
    char word[30];
    char meaning[50];
    struct node *next;
};


void insert(struct node **head, char *word, char *meaning) 
{
    struct node *new_node = (struct node*) malloc(sizeof(struct node));
    strcpy(new_node->word, word);
    
    // 去掉meaning末尾的换行符
    size_t len = strlen(meaning);
    if (len > 0 && meaning[len-1] == '\n') {
        meaning[len-1] = '\0';
    }
    strcpy(new_node->meaning, meaning);
    new_node->next = NULL;

    if (*head == NULL) 
    {
        *head = new_node;
    } 
    else if (strcasecmp((*head)->word, word) > 0) 
    {
        new_node->next = *head;
        *head = new_node;
    } 
    else 
    {
        struct node *curr = *head;
        // 先判断curr->next是否存在,再做字符串比较,避免空指针
        while (curr->next != NULL && strcasecmp(curr->next->word, word) < 0) 
        {
            curr = curr->next;
        }
        new_node->next = curr->next;
        curr->next = new_node;
    }
}


void print_list(struct node * head) 
{
    struct node * cur = head;
    // 遍历到cur本身不为NULL,确保所有节点都被打印
    while (cur != NULL) 
    {
        printf("%s : %s\n", cur->word, cur->meaning);
        cur = cur->next;
    }
}

int main() 
{
    FILE *fp;
    char line[150];

    fp = fopen("randdict.txt", "r");

    if (fp == NULL) 
    {
        printf("无法打开文件。\n");
        exit(1);
    }

    struct node *head = NULL;

    while (fgets(line, 150, fp)) 
    {
        char *new_word = strtok(line, ":");
        char *new_meaning = strtok(NULL, ":");
        // 确保分割成功再插入,避免空指针传入insert
        if (new_word != NULL && new_meaning != NULL) {
            insert(&head, new_word, new_meaning);
        }
    }

    fclose(fp);

    print_list(head);

    // 释放链表内存,避免内存泄漏
    struct node *temp;
    while (head != NULL) {
        temp = head;
        head = head->next;
        free(temp);
    }

    return 0;
}

三、关键修复说明

  • print_list函数:将循环条件改为cur != NULL,移除多余的提前返回判断,确保每个节点都被打印。
  • insert函数:调整while循环的判断顺序,先检查curr->next != NULL再做字符串比较;统一使用strcasecmp保证忽略大小写的排序一致性;添加代码去掉meaning中的换行符。
  • main函数:添加了分割结果的非空判断,避免无效插入;最后添加链表内存释放代码,防止内存泄漏。

内容的提问来源于stack exchange,提问作者이주연

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:38:08