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

C语言FILE/IO单词计数结果存在微小偏差问题求助

问题成因

统计结果出现固定差值1的核心原因如下:

  • 核心计数逻辑存在遗漏:现有代码只有在碰到空白分隔符(空格、换行、制表符、空字符)时才会触发单词数+1的操作,如果文件末尾是普通单词字符、没有尾随空白符,循环读到EOF就直接终止,最后一个单词不会被计入总数。你测试的第一个文件结果正确,是因为它末尾带有空白分隔符,最后一个单词在循环内就完成了计数;另外两个结果少1的文件都没有尾随空白,因此各漏算了1个末尾单词。
  • 存在隐藏类型兼容bug:fgetc()的返回值是int类型(用来表示值为-1的EOF标识),你用char类型变量存储返回值,当编译环境下char为有符号类型、文件中存在值为0xFF的字符时,会被误判为EOF导致读取提前终止,只是这次的测试文件没有触发该问题。
  • 缺少鲁棒性判断:代码没有校验fopen()的执行结果,如果文件不存在、权限不足导致打开失败,直接操作空文件指针会触发程序崩溃。
修复方案

针对以上问题对应修改逻辑即可:

  1. 将存储读取字符的变量类型从char改为int,匹配fgetc()的返回值类型,避免EOF误判
  2. 文件读取循环结束后,补充判断当前是否处于单词内状态,如果是则给总单词数+1,补上末尾漏算的最后一个单词
  3. 增加文件打开失败的判断逻辑,避免空指针访问

修复后的完整代码如下:

int countwords(const char* filename) {
    int z; // 改为int类型接收fgetc返回值
    int inw = 0;
    int words = 0;
    FILE *ed;
    ed = fopen(filename, "r");
    // 增加文件打开失败判断
    if (ed == NULL) {
        return -1; // 打开失败返回错误标识,可根据需求自定义错误处理逻辑
    }
    while ((z = fgetc(ed)) != EOF ){
        if (z == ' ' || z == '\n' || z == '\t' || z == '\0') {
            if(inw) {
                inw = 0;
                words++;
            }
        } else {
            inw = 1;
        }
    }
    // 补充文件末尾未以空白结尾时的最后一个单词计数
    if (inw) {
        words++;
    }
    fclose(ed);
    return words;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:27:29