【问题标题】:how to read/write sequnce of bits bit by bit in c++如何在 C++ 中逐位读/写位序列
【发布时间】:2021-03-12 16:20:00
【问题描述】:

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

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

我想将 Huffman 编码算法生成的位序列(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;
}

输出

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

【问题讨论】:

  • 文件(流)至少在字节级别上工作。没有办法将单个位放入文件中。您必须以字节为单位收集位并写入后者。
  • @Scheff 所以我需要制作一个 8 位的缓冲区然后处理它们?
  • 8 位缓冲区?你的意思是一个字节。 charunsigned char?
  • 您必须编写自己的机制来写入字节(这很容易),但您可以写入文件的最小时间是一次一个字节。
  • 对于开发,如果您不介意文件空间的浪费,您可能会发现读取/写入'0''1' 字符而不是执行逐字节缓冲。

标签: c++ character-encoding bit huffman-code read-write


【解决方案1】:

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

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

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

完成后,如果缓冲区中还有位,则将最后的 1 到 7 位写入一个字节。您需要仔细考虑您是如何做到这一点的,以及如何知道有多少位,以便您可以正确解码另一端的位。

使用您的语言中的位操作完成累积和提取。在 C++(和许多其他语言)中,它们是 &amp;(和)、|(或)、&gt;&gt;(右移)和 &lt;&lt;(左移)。

例如,要在缓冲区中插入一位 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;
}

...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多