用 C 语言从二进制文件中读取位

Posted

技术标签:

【中文标题】用 C 语言从二进制文件中读取位【英文标题】:reading bits from a binary file in C language 【发布时间】:2021-08-17 23:21:18 【问题描述】:

每 3 位代表一行或一列。我需要每 3 位读取一次并将它们存储在一个变量中。

这是我目前的代码:

typedef unsigned char BYTE

void main()


    FILE* fh = fopen("knightPath.bin", "rb");
    checkFileOpening(fh);

    BYTE ch ,ch1, ch2;

    fread(&ch, sizeof(BYTE), 1, fh);
    ch1 = ch >> 5; /* first 3 bits 'C' */
    ch2 = ch << 3 >> 5; /* second 3 bits '5' */

    fclose(fh);

问题是从字母 A 中读取位,因为我在变量 ch 中有 2 位,而下一位将在我从文件中读取的下一个 BYTE 中。

我想过使用面具,但我不确定如何。

有什么想法吗?我怎样才能解决这个问题?

谢谢

【问题讨论】:

始终检查fopen() 返回的FILE* 是否为NULL。如果是NULL,你应该抛出一些错误。另外,检查fread()的返回值。 通过编写一个具有字节缓冲区(如unsigned int)和位计数的函数。如果缓冲区中有足够的位,则提取它们并更新变量。如果不是,则从文件中读取另一个字节并将其与缓冲区合并。如果是结尾,return -1(例如)。 我在我的函数 checkFileOpening(fh); 中这样做了 请发布完整代码以便更好地分析。 @WeatherVane 你有代码示例吗? 【参考方案1】:

请您尝试以下方法:

#include <stdio.h>
#include <stdlib.h>
#define FILENAME "knightPath.bin"

int main() 
    FILE *fp;
    int c, ch1, ch2;
    int remain = 0;                     // remaining buffer (FIFO) size in bit
    int buf = 0;                        // FIFO of bit stream

    if (NULL == (fp = fopen(FILENAME, "rb"))) 
        fprintf(stderr, "can't open %s\n", FILENAME);
        exit(1);
    

    while (1) 
        if (remain < 6)                // if the FIFO size < 6
            c = fgetc(fp);              // then read next byte
            if (c == EOF) return EXIT_SUCCESS;
            remain += 8;                // increase the buffer size
            buf = (buf << 8) + c;       // append the byte to the FIFO
        
        ch1 = (buf >> (remain - 3)) & 7;// get the leftmost 3 bits
        ch2 = (buf >> (remain - 6)) & 7;// get the next 3 bits
        printf("ch1 = %c, ch2 = %d\n", ch1 + 'A', ch2 + 1);
        remain -= 6;                    // decrease the FIFO size
        buf &= ((1 << remain) - 1);     // clear the processed bits
    

输出:

ch1 = C, ch2 = 5
ch1 = A, ch2 = 4
ch1 = B, ch2 = 3
ch1 = D, ch2 = 1
ch1 = E, ch2 = 3

【讨论】:

【参考方案2】:

要从二进制文件中读取二进制数据,我们需要使用这行代码。 `无符号字符缓冲区[10]; 文件 *ptr;

ptr = fopen("test.bin","rb"); // r 读取,b 二进制

fread(buffer,sizeof(buffer),1,ptr); // 读取 10 个字节到我们的缓冲区`

【讨论】:

OP 知道这一点:但想知道如何提取和对齐可能跨越多个字节的位字段。

以上是关于用 C 语言从二进制文件中读取位的主要内容,如果未能解决你的问题,请参考以下文章

用python从二进制文件中读取32位带符号的ieee 754浮点?

从二进制文件中重复 fread() 16 位

从二进制文件中读取并转换为双精度?

在 C++ 中写入整数并从二进制文件中读取它们:字节数 mismaych

使用 ifstream 从二进制文件中读取 4 个字节

如何从二进制文件中获取应用程序的版本号?