我必须将各个位写入文件(对于霍夫曼代码)。为此,我将位发送到一个函数,该函数对它们进行缓冲,直到填充一个字节,然后返回该字节。我不明白为什么它不起作用,该函数输出错误的字节(但没有错误)。 这是bitsBuffer函数:
// Buffers bits until one byte is filled, the returns it and return code turns positive
int bitsBuffer(char inByte, char nBits, char* outByte, char finish)
{
int i;
static short unsigned buffer = 0;
static char unsigned offset = 0;
// Very readable way to add nBits Bits to buffer
buffer |= (inByte & ~(~0 << nBits)) << offset;
offset += nBits;
if (offset >= 8) {
*outByte = (char)buffer;
buffer >>= 8;
offset -= 8;
return 1;
}
if (finish) {
buffer = 0;
if (offset) {
*outByte = (char)buffer;
offset = 0;
return 1;
}
offset = 0;
return 0;
}
return 0;
}
我使用这个程序来测试位缓冲区,然后将输出通过管道传输到
xxd -b
以查看位:
#include "bitsHandler.h"
#include <stdio.h>
int main()
{
char a[] = { 0b0110, 0b1, 0b100010, 0b111, 0b100110, 0b0 };
char b[] = { 4, 1, 6, 3, 6, 1 };
char c[100];
int counter = 0;
for (int i = 0; i < 6; i++) {
if (bitsBuffer(a[i], b[i], &c[counter], 0)) {
counter++;
}
}
if (bitsBuffer(0, 0, &c[counter], 1)) {
counter++;
}
fwrite(c, sizeof(char), counter, stdout);
}
我在纸上复制了该函数(手动完成了每一步),但我找不到我的错误。感谢帮助。
除了您的位顺序有点奇怪(因为您将新位添加到缓冲区顶部并将它们从底部取出)这一事实之外,您在
finish
路径中还有一个错误。
if (finish) {
buffer = 0; // <<<==== This is a bug I think
if (offset) {
*outByte = (char)buffer;
offset = 0;
return 1;
}
offset = 0;
return 0;
}
当我干运行你的测试数据时,当你的代码到达标记为“我认为这是一个错误”的行时,
buffer
仍然有一些位。即0b01001
和offset
是5。最后五个位永远不会被写入输出。