将boost :: dynamic_bitset写入文件

时间:2013-09-29 14:11:24

标签: c++ boost c++11

我正在实现Shannon-Fano编码算法,我想输出符号代码作为位。

例如,在下面的代码中,我逐行读取输入文件(fin stream)中的符号,用std::string填充符号代码(来自std::map<unsigned short, std::string> symbolCodes)算法,然后用boost::dynamic_bitset的内容构造currentOutString。然后我尝试输出bitset,但在输出文件中,bitset中的每个“true”或“false”值占用1个字节而不是1个位。

if (fin.is_open() && fout.is_open()) {
    std::string currentInString;
    std::string currentOutString;

    while (getline(fin, currentInString)) {
        boost::dynamic_bitset<> bitSet;
        for (auto & ref : currentInString) {
            currentOutString += symbolCodes[ref];
        }

        for (auto & ref : currentOutString) {
            if (ref == '0') bitSet.push_back(0);
            if (ref == '1') bitSet.push_back(1);
        }
        fout << bitSet;

        bitSet.clear();
        currentOutString.erase();
    }
}

fout流以std::ios_base::binary模式打开。例如,我有单词“file”,代码是e: 00, f: 01, i: 10, l: 11。如何输出我的bitset,输出文件占用8位而不是8位?

提前感谢您的帮助,并对可能的语言错误表示抱歉。

1 个答案:

答案 0 :(得分:2)

这实际上不是dynamic_bitset的错;它是iostream的。

以下代码打印

123
----.

cout

#include <iostream>
#include <boost/dynamic_bitset.hpp>

int main() {
    using namespace std;
    using namespace boost;

    auto bitset = dynamic_bitset<>(32, 0x0a333231); // "123\n" in little endian
    bitset.append(0x2d2d2d2d); // "----"
    bitset.append(0x0a2e); // ".\n"
    // bitset.size() is at least 96 here

    auto ulong_mask = dynamic_bitset<>(bitset.size(), 0xFFFFFFFFul);
    while(bitset.any()) {
        unsigned long ulong = (bitset & ulong_mask).to_ulong();
        cout.write(reinterpret_cast<char*>(&ulong), sizeof(ulong));

        bitset >>= 32;
    }
}

请注意使用cout.write()代替operator <<。它输出字节 as-is ,没有任何格式化和转换为ASCII字符串(想想itoa()或类似的东西)。


还有一点:因为dynamic_bitset不提供连续的存储保证和/或访问,我们必须通过块来读出大的位集,最好是更大的块;例如unsigned long

在某些体系结构中,sizeof(unsigned long)将为8,因此我们实际上可以使用更大的ulong_maskULONG_MAX会这样做),并相应地转换(8 * sizeof(unsigned long))。用那个。 (上面的32是硬编码的,为了清楚说明)。