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

基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:54:58