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,提问作者이주연
相关产品推荐
相关产品推荐

