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
相关产品推荐
相关产品推荐

