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

C语言二进制文件读取:如何逐位读取单个比特?是否有fgetbit()函数?

逐位读取文件比特:自己实现fgetbit()

嘿,好问题!标准C库确实没有提供fgetbit()这种直接读取单个比特的函数——毕竟文件IO的最小操作单位是字节。不过我们完全可以基于现有的标准函数封装一个自己的fgetbit(),完美满足你逐位读取的需求。

实现思路

核心逻辑是用一个缓冲区保存当前读取的字节,再用一个计数器记录已经从这个字节里取走了多少个比特:

  • 当缓冲区的所有比特都被读取完时,调用fgetc()读取新的字节到缓冲区
  • 每次调用时,从缓冲区的对应位置提取单个比特,更新计数器

完整实现代码

#include <stdio.h>

// 自定义的逐位读取函数
int fgetbit(FILE *file) {
    // 静态变量:保存当前字节缓冲区和已读取比特数(跨调用保持状态)
    static unsigned char buffer = 0;
    static int bits_read = 8; // 初始设为8,表示需要读取新字节

    // 缓冲区已空,读取新的字节
    if (bits_read == 8) {
        int c = fgetc(file);
        if (c == EOF) {
            return EOF; // 返回EOF表示文件结束或读取错误
        }
        buffer = (unsigned char)c;
        bits_read = 0;
    }

    // 提取当前要读取的比特(从最高位到最低位依次取出)
    int bit = (buffer >> (7 - bits_read)) & 1;
    bits_read++;

    return bit;
}

// 使用示例
int main() {
    FILE *infile = fopen("input.txt", "rb");
    if (!infile) {
        perror("Failed to open file");
        return 1;
    }

    int my_bit;
    // 循环读取每一位,直到文件结束
    while ((my_bit = fgetbit(infile)) != EOF) {
        printf("%d ", my_bit);
    }
    printf("\n");

    fclose(infile);
    return 0;
}

代码说明

  1. 静态变量的作用:buffer和bits_read是静态变量,会在多次调用fgetbit()时保留它们的值,这样我们就能持续跟踪当前字节的读取进度。
  2. 比特提取逻辑:(buffer >> (7 - bits_read)) & 1的作用是把当前要读取的位移到最低位,再通过与1的按位与操作取出该位的值(0或1)。比如读取第一个比特时,bits_read=0,右移7位,取出最高位。
  3. EOF处理:当fgetc()返回EOF时,说明文件已经读完或者读取出错,此时我们的fgetbit()也返回EOF,方便外部判断循环结束。

注意事项

  • 必须以二进制模式打开文件("rb"),避免文本模式下的换行符转换(比如Windows下的\r\n转\n)破坏原始字节内容。
  • 这个实现是线程不安全的,因为静态变量是全局共享的。如果需要在多线程环境使用,可以把buffer和bits_read封装到一个结构体中,作为参数传递给fgetbit()。
  • 对于你提到的"hello"示例:'h'的ASCII值是104,二进制为01101000,调用fgetbit()时会依次返回0, 1, 1, 0, 1, 0, 0, 0,所以第二次调用时my_bit的值就是1,完全符合你的预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:05:40