基于Linked Lists统计字符重复数的C代码无输出问题排查
代码无输出问题排查(基于链表统计字符重复行)
给定如下6×6字符矩阵:
X A E I O U U X A E I O O U X A E I I O U X A E E I O U X A X Y Z X Y X
任务是找出字符重复次数最多的行(本例为第6行,包含3个X)。计划用Linked Lists实现,思路为:
- 构建包含字符、出现次数及所在行的节点结构
- 通过
while循环逐个扫描每个字符,检查当前行是否已存储该字符:若已存储则计数加1,否则新建节点并将计数初始化为1
编写了如下C代码,但运行后无任何输出,以下是问题排查及修正方案:
原代码
#include <stdio.h> #include <stdlib.h> typedef struct Node { int row; int count; char c; struct Node *next; }node; node *createNode(char *name) { FILE *file; file= fopen(name,"r"); if(file==NULL) { printf("Error opening file...."); exit(1); } int n=6; char str[6][6]; char c; node *head=NULL; int i=0; int j=0; while(fscanf(file,"%c ",&str[i][j])!=EOF) { int found=0; int r=0; node *p=head; while (p) { if(p->c==str[i][j] && p->row==i) { found=1; break; } } if(found) { p->count++; } else { node *tmp= malloc(sizeof (node)); if(tmp==NULL) { printf("Error allocating memory!"); exit(1); } tmp->c=str[i][j]; tmp->row=i; tmp->count=1; tmp->next=head; head=tmp; } i++; if(i==6) { i=0; j++; } } fclose(file); return head; } void printList(node *head) { node *tmp=head; int i=1; while(tmp != NULL) { printf("Node %d:\nchar->%c\nrow->%d\ncount->%d\n\n",i,tmp->c,tmp->row,tmp->count); i++; tmp=tmp->next; } } int main() { char name[]={"file"}; node *head=NULL; head=createNode(name); printList(head); return 0; }
核心问题及修正
1. 链表遍历死循环
内层while (p)循环中未移动指针p = p->next,导致一旦链表存在节点,程序会无限卡在这个循环里,永远无法执行到后续的打印逻辑。
修正代码:
node *p=head; while (p) { if(p->c==str[i][j] && p->row==j) // 同时修正行号匹配错误,见下文 { found=1; break; } p = p->next; // 新增:移动指针遍历链表 }
2. 行号匹配错误
原代码中把列索引i赋值给row,但j才是实际的行索引(i是列索引,从0到5;j是行索引,从0到5),导致字符的行归属完全错误,无法正确统计同一行的字符重复。
修正代码:
// 匹配条件中改为p->row == j if(p->c==str[i][j] && p->row==j) // 新建节点时行号赋值为j tmp->row = j;
3. 文件读取格式问题
fscanf(file,"%c ",&str[i][j])中的后缀空格会匹配任意空白字符(包括换行),结合i和j的计数逻辑会导致字符读取顺序混乱,甚至提前结束读取。建议改为fscanf(file, " %c", &str[i][j])(前缀空格跳过所有前导空白,确保每次读取一个有效字符)。
4. 数组索引逻辑混淆
原代码中str[i][j]的第一维是列、第二维是行,虽然不会越界,但逻辑上不符合常规的行优先存储习惯,容易引发后续错误,建议改为str[j][i](行在前,列在后),同时调整计数逻辑保持一致。
5. 冗余代码修正
char name[]={"file"};写法冗余,改为char name[] = "file";更规范。
修正后代码示例(关键部分)
node *createNode(char *name) { FILE *file; file= fopen(name,"r"); if(file==NULL) { printf("Error opening file...."); exit(1); } int n=6; char str[6][6]; node *head=NULL; int i=0; // 列索引 int j=0; // 行索引 while(fscanf(file, " %c", &str[j][i])!=EOF) // 行优先存储,修正读取格式 { int found=0; node *p=head; while (p) { if(p->c==str[j][i] && p->row==j) { found=1; break; } p = p->next; // 遍历链表 } if(found) { p->count++; } else { node *tmp= malloc(sizeof (node)); if(tmp==NULL) { printf("Error allocating memory!"); exit(1); } tmp->c=str[j][i]; tmp->row=j; tmp->count=1; tmp->next=head; head=tmp; } i++; if(i==6) { i=0; j++; } } fclose(file); return head; }
内容的提问来源于stack exchange,提问作者Severjan Lici
相关产品推荐
相关产品推荐

