我正在实现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位?
提前感谢您的帮助,并对可能的语言错误表示抱歉。
答案 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_mask
(ULONG_MAX
会这样做),并相应地转换(8 * sizeof(unsigned long))
。用那个。 (上面的32是硬编码的,为了清楚说明)。