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

C语言:仅用指定IO函数统计不区分大小写单词数的程序故障排查

代码问题排查与修复:不区分大小写统计文件中指定单词出现次数

核心问题分析

1. 运算符优先级错误导致字符获取完全失效

代码里的循环条件while (c=lower(fgetc(fin)) != EOF )存在优先级问题:!=的优先级比=高,实际执行逻辑是c = (lower(fgetc(fin)) != EOF),这会让c被赋值为0或1(布尔判断结果),根本不是读取到的字符,后续匹配自然全错。

2. 目标单词长度赋值完全错误

char dog[] = "dog"的有效匹配字符数是3,但代码里写了n = 7,导致x == n的统计触发条件永远无法满足,结果res一直是0。

3. 字符类型不匹配导致EOF判断异常

fgetc返回的是int类型(要容纳EOF这个特殊的负整数值),用char c接收的话,在有符号char的系统里,EOF会被截断成0xFF,无法正确判断文件是否读完;同时lower函数的参数和返回值用char也会导致同样的截断问题。

4. 匹配逻辑的小瑕疵

当前逻辑在部分匹配失败时直接重置x为0,但如果遇到类似dodog的场景,第三个字符d不匹配o后,第四个字符d本可以直接匹配目标单词的第一个字符,原逻辑会多一次无效的重置,需要微调。

修复后的代码

#include <stdio.h>

// 改成int类型处理,避免EOF截断问题
int lower(int c){
    if(c >= 'A' && c <= 'Z')
        return c + 'a' - 'A';
    return c;
} 

int main(int argc, char* argv[]){
  
  char dog[] = "dog";
  int x = 0; // 匹配到的字符数
  int n = 3; // 目标单词的有效长度("dog"共3个字符)
  int res = 0; // 总匹配次数

  FILE* fin = fopen("dog.txt","r");
  if (fin == NULL) {
      puts("File in error");
      return 1;
  }

  int c; // 改用int类型,正确接收fgetc的返回值(包含EOF)
  // 加括号修正运算符优先级,确保先赋值再判断
  while ((c = lower(fgetc(fin))) != EOF ){
      if (c == dog[x]){
          x++;
          if (x == n){
              res++;
              x = 0;
          }
      }
      else {
          x = 0;
          // 优化:如果当前字符刚好是目标单词开头,直接开始计数
          if (c == dog[0]) {
              x = 1;
          }
      }
  }

  fclose(fin);

  // 注意:"w"模式会清空原文件内容,要保留原内容请改用"a"模式或先存原内容再写入
  FILE* fout = fopen("dog.txt","w");
  if (fout == NULL) {
      puts("File out error");
      return 1;
  }
  
  fprintf(fout, "%i", res);
  
  fclose(fout);

  return 0;
}

额外说明

  • 把c改成int类型,确保能正确识别EOF;
  • 修正了循环条件的运算符优先级问题;
  • 调整目标单词长度为正确的3;
  • 优化了部分匹配失败后的逻辑,避免遗漏可能的开头匹配;
  • 如果需要保留原文件内容并追加统计结果,把打开输出文件的模式从"w"改成"a"即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:45:37