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; }
代码说明
- 静态变量的作用:
buffer和bits_read是静态变量,会在多次调用fgetbit()时保留它们的值,这样我们就能持续跟踪当前字节的读取进度。 - 比特提取逻辑:
(buffer >> (7 - bits_read)) & 1的作用是把当前要读取的位移到最低位,再通过与1的按位与操作取出该位的值(0或1)。比如读取第一个比特时,bits_read=0,右移7位,取出最高位。 - 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
相关产品推荐
相关产品推荐

