【发布时间】:2015-09-28 16:42:13
【问题描述】:
我正在编写霍夫曼编码,一切正常,直到我尝试将结果保存到存档文件中。我们的老师让我们用这样的功能来做(每次都需要一点时间,其中8个应该输出一个字节):
long buff=0;
int counter=0;
std::ofstream out("output", std::iostream::binary);
void putbit(bool b)
{
buff<<=1;
if (b) buff++;
counter++;
if (counter>=8)
{
out.put(buff);
counter=0;
buff=0;
}
}
我尝试了一个输入这样的位序列的示例:
0011001011001101111010010001000001010101101100
但二进制模式的输出文件只包含:1111111
由于buff 变量的数字正确(25 102 250 68 21 108),我建议我在笔记本中写错了代码,这行有问题:
out.put(buff);
我试图用这一行删除它:
out << buff;
但得到:1111111111111111
另一种方法是:
out.write((char *) &buff, 8);
给出:
100000001000000010000000100000001000000010000000
它看起来最接近正确答案,但仍然无法正常工作。
也许我对文件输出有些不理解。
问题:
您能解释一下如何使它工作以及为什么以前的变体是错误的吗?
更新: 输入来自这个函数:
void code(std::vector<bool> cur, std::vector<bool> sh, std::vector<bool>* codes, Node* r)
{
if (r->l)
{
cur.push_back(0);
if (r->l->symb)
{
putbit(0);
codes[(int)r->l->symb] = cur;
for (int i=7; i>=0; i--)
{
if ((int)r->l->symb & (1 << i))
putbit(1);
else putbit(0);
}
}
else
{
putbit(0);
code(cur, sh, codes, r->l);
}
cur.pop_back();
}
if (r->r)
{
cur.push_back(1);
if (r->r->symb)
{
putbit(1);
codes[(int)r->r->symb] = cur;
for (int i=7; i>=0; i--)
{
if ((int)r->r->symb & (1 << i))
putbit(1);
else putbit(0);
}
}
else
{
putbit(1);
code(cur, sh, codes, r->r);
}
cur.pop_back();
}
}
【问题讨论】:
-
我看到该代码唯一的错误是您没有检查函数的返回值是否有错误。
-
我刚刚在您的输入上运行了您的代码,它生成了正确的文件。你能展示你用来调用你的函数的代码吗?
-
我实际上运行了您的代码并且它可以工作,尽管我会使用
char而不是long作为缓冲区变量。也许向我们展示您是如何在代码中实际使用此函数的?另外,“正确的数字(25 102 250 68 21 108)”是什么?你应该告诉我们你想要达到的目标。 -
asig 和 Ishamael,您能说出哪些变体有效吗? asig,我的意思是二进制操作正常工作,并且在输出到文件 buff 之前具有正确的值
-
@Tami 我直接复制粘贴了你的函数,
out.put( buff )。我现在明白你的意思了。