如何在 C++ 中逐位 read/write 位序列

how to read/write sequnce of bits bit by bit in c++

我已经在 C++ 中实现了 Huffman 编码算法,并且运行良好。我想创建一个文本压缩算法。

在数字世界的每一个文件或数据的背后,都有0/1。

我想在文件中保留由霍夫曼编码算法生成的位序列(0/1)。

我的目标是保存要存储的文件中使用的位数。我将用于解码的元数据存储在一个单独的文件中。我想一点一点地写入文件,然后在c++中一点一点地读取相同的数据。

我在 二进制模式 中面临的问题是它不允许我一点一点地放置数据。 我想将“10101”一点一点地放入文件,但它一次放入每个字符的 asci 值或 8 位。

代码

#include "iostream"
#include "fstream"
using namespace std;

int main(){
    ofstream f;
    f.open("./one.bin", ios::out | ios::binary);
    f<<"10101";
    f.close();

    return 0;
}

输出

感谢任何帮助或指向帮助的指示。谢谢。

“二进制模式”仅表示您已请求您写入的实际字节不会被行尾转换损坏。 (这只是 Windows 上的一个问题。没有其他系统需要故意破坏您的数据。)

您仍在以二进制模式一次写入一个字节。

要写入位,您需要将它们累积成一个整数。为方便起见,使用无符号整数。这是您的位缓冲区。您需要决定是从最少到最多还是从最多到最不重要的位置累积它们。一旦累积了八位或更多位,就将一个字节写入文件,并从缓冲区中删除这八位。

完成后,如果缓冲区中还有位,则将最后的一到七位写到一个字节中。你需要仔细考虑你到底是怎么做到的,以及如何知道有多少比特,这样你才能正确解码另一端的比特。

累加和提取是使用您的语言中的位运算完成的。在 C++(和许多其他语言)中,它们是 &(和)、|(或)、>>(右移)和 <<(左移)。

例如,要将一位 x 插入您的缓冲区,然后在 y 中插入三位,以最重要位置的最早位结束:

unsigned buf = 0, bits = 0;

...

// some loop
{
   ...

   // write one bit (don't need the & if you know x is 0 or 1)
   buf = (buf << 1) | (x & 1);
   bits++;

   ...

   // write three bits
   buf = (buf << 3) | (y & 7);
   bits += 3;

   ...

   // write bytes from the buffer before it fills the integer length
   if (bits >= 8) {     // the if could be a while if expect 16 or more
       // out is an ostream -- must be in binary mode if on Windows
       bits -= 8;
       out.put(buf >> bits);
   }

   ...

}

...

// write any leftover bits (it is assumed here that bits is in 0..7 --
// if not, first repeat if or while from above to clear out bytes)
if (bits) {
    out.put(buf << (8 - bits));
    bits = 0;
}

...