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

使用fgetc统计文件中指定十六进制数的实现及问题代码排查

能否使用fgetc统计文件中特定十六进制数值的出现次数

完全可以。fgetc每次调用会从以二进制模式打开的文件中读取1个字节,刚好匹配单字节十六进制值的统计场景,你给出的示例中查询0xFF返回1的需求完全可以通过该函数实现。
你现有代码运行结果不符合预期,是几个典型的C语言文件操作错误导致的。

现有代码的错误点
  • 文件读取循环逻辑错误:while(!feof(in))是C语言文件操作的常见问题。feof只有在已经触发过文件末尾读取操作后才会返回真值,当读完文件最后一个有效字节后,下一次fgetc调用会返回EOF(值为-1),这个无效值会被你写入数组,同时计数器i会多累加1次。
  • 无效值误判:fgetc返回值是int类型,设计目的就是为了区分0x00~0xFF范围的有效字节和特殊标记EOF。你把返回值直接存入unsigned char类型的数组时,EOF(-1)会被转换为0xFF,这也是你统计0xFF时结果偏大的核心原因——读取到文件末尾产生的假0xFF也被计入了统计。
  • 数组越界风险:你定义的存储数组固定长度为1000字节,一旦目标文件大小超过1000字节,写入数组时会发生内存越界,引发程序崩溃或逻辑异常。
  • 统计范围错误:统计时你遍历了整个1000长度的数组,而非实际从文件中读取到的有效字节范围。数组初始化时所有元素都是0,如果查询值是0x00,所有未写入内容的数组元素都会被计入结果,统计值完全错误。
  • 缺少异常校验:如果a.dat不存在、当前用户没有读取权限,fopen会返回NULL,后续直接操作空指针会导致程序直接崩溃。
修正后的实现代码

实际上统计字节出现次数根本不需要把整个文件读入内存存储,边读取边比对计数即可,既不会有内存长度限制,运行效率也更高,修正后的代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *in = NULL;
    int read_byte;
    unsigned int target_val;
    int count = 0;

    // 二进制只读模式打开文件,校验打开结果
    in = fopen("a.dat", "rb");
    if (in == NULL) {
        printf("打开文件a.dat失败,请检查文件是否存在及权限\n");
        return EXIT_FAILURE;
    }

    // 读取用户输入的待查询十六进制值
    printf("请输入要查询的单字节十六进制值(例如输入FF代表0xFF):");
    scanf("%x", &target_val);
    if (target_val > 0xFF) {
        printf("输入非法,单字节十六进制值范围为00~FF\n");
        fclose(in);
        return EXIT_FAILURE;
    }

    // 逐字节读取文件,匹配则计数
    while ((read_byte = fgetc(in)) != EOF) {
        if ((unsigned char)read_byte == target_val) {
            count++;
        }
    }

    // 输出结果到控制台和b.txt
    printf("统计结果:%d\n", count);
    FILE *out = fopen("b.txt", "wb");
    if (out != NULL) {
        fprintf(out, "%d\n", count);
        fclose(out);
    }

    fclose(in);
    return EXIT_SUCCESS;
}
代码逻辑说明
  • 移除了固定长度数组,采用逐字节读取即时比对的逻辑,支持任意大小的文件统计,不存在数组越界问题。
  • 修正了文件读取循环判断条件,直接通过fgetc返回值是否为EOF判断是否读到文件末尾,避免多读无效字节。
  • 比对时将fgetc返回的int类型值显式转为unsigned char,保证和0~0xFF范围的目标值匹配逻辑正确,不会把EOF误判为有效字节0xFF。
  • 增加了文件打开、输入值合法性校验,避免异常场景下程序崩溃。
  • 统计范围仅覆盖实际从文件中读取到的有效字节,不会引入无关初始值的干扰。

用你给出的测试字节序列验证:输入FF时,程序会正确返回统计值1,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:42:28