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

C语言文件字符串计数函数存在Bug,请求技术排查帮助

文件末尾无换行符的目标字符串无法统计的Bug修复

作业要求

  • 编写名为countString的函数,接收用户输入的字符串,统计其在notes.txt文件中的出现次数并返回,未出现则返回0。
  • 输入字符串长度不超过15个字符。
  • 示例:输入Hello,输出2

原代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
    
int countString()
{
    char str1[16];
    char str2[16];
    char *str;
    int strCount = 0;

    //get user input for the string he wants to search and count
    str = fgets(str1, 16, stdin);
    
    FILE *fp1 = fopen("notes.txt", "r");
    if (fp1 == NULL)
    {
        puts("\nCannot open any such file");
        return 0;
    }
    
    /* subtle bug is that the last word is not getting counted if 
       the file is saved on the same line as the word instead of a
       new line
       example problem: notes.txt contains: two words "shut"
       shut shut and file is saved after the second 't' in the 
       second shut, this shut is not being Counted.
     */
    
    while (fgets(str2, sizeof(str2), fp1) != NULL)
    {
        fputs(str2, stdout);
        if (strcmp(str, str2) == 0)
            strCount++;
    }

    fclose(fp1);
    return strCount;
}

int main()
{
    printf("\n%d", countString());
    getch();
    return 0;
}

问题描述

当notes.txt中目标字符串后无换行符时(例如内容为shut shut且末尾无换行),末尾的字符串无法被统计。此外,原代码仅能统计整行等于目标字符串的情况,无法处理同一行内多次出现的目标字符串。

问题根源

  1. 输入字符串带换行符:fgets会将用户输入时的回车(\n)一并读取到缓冲区,导致输入字符串(如"shut\n")与文件中无换行的"shut"对比不相等。
  2. 匹配逻辑错误:原代码通过整行对比(strcmp)判断是否匹配,而非在每行中查找目标字符串的出现次数,既无法处理同一行内的多次出现,也无法匹配行中单独存在的目标字符串。

修复方案

  1. 移除输入字符串的换行符:使用strcspn找到换行符的位置,将其替换为字符串结束符\0。
  2. 逐行查找目标字符串的所有出现:在每行中使用strstr循环查找目标字符串,每次找到后偏移指针继续搜索该行剩余内容,统计次数。
  3. 适配无换行的末尾行:fgets读取无换行的末尾行时,会正常读取内容(仅不含\n),此时在该行中查找目标字符串即可完成统计。

修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
    
int countString()
{
    char target[16];
    char line[256]; // 扩大行缓冲区,避免长行截断
    int count = 0;

    // 读取用户输入并移除换行符
    if (fgets(target, sizeof(target), stdin) == NULL) {
        return 0;
    }
    target[strcspn(target, "\n")] = '\0'; // 去掉输入的换行符

    FILE *fp = fopen("notes.txt", "r");
    if (fp == NULL)
    {
        puts("\nCannot open any such file");
        return 0;
    }
    
    // 逐行读取文件,查找目标字符串的所有出现
    while (fgets(line, sizeof(line), fp) != NULL)
    {
        char *pos = line;
        // 循环查找当前行中的目标字符串
        while ((pos = strstr(pos, target)) != NULL) {
            count++;
            // 偏移指针,避免重复匹配同一位置
            pos += strlen(target);
        }
    }

    fclose(fp);
    return count;
}

int main()
{
    printf("\n%d", countString());
    getch();
    return 0;
}

说明

  • 扩大行缓冲区至256字节,避免长行被截断导致匹配失败。
  • 使用strstr循环查找,可统计同一行内目标字符串的多次出现。
  • 移除输入的换行符后,无论文件中的目标字符串是否带换行,都能正确匹配。

内容的提问来源于stack exchange,提问作者Surya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:10:22