0

晚上好,我是 C++ 新手,遇到了一个问题,尽管在这里阅读了很多页面,但我还是无法解决。我有一个包含十六进制值的文件,需要读取和压缩,然后写入一个新文件。示例序列如下所示:

C9 CB FF 01 06(每个字节[8位]代表一个数字)

压缩从第一个数字开始,然后只将差异写入下一个数字(差异是半字节 [4 位])。从C9到CB的例子:差值=2。如果差值大于7,不能用半字节表示,我们用0x8来标记一个新的开始。0xFF-0xCB > 7 所以序列看起来像这样(整个压缩代码):

C9 28 FF 15(整个字节(0xC9和0xFF)的混合代表数字和代表与下一个数字的差异的半字节。现在解决我的问题。我正在使用fstream并将字节写入新文件,半字节被存储以组合对可以写入文件的字节的另一个半字节。但是它仅适用于小于 128 的字节,因此我无法将大于 0x7F 的值写入文件。我用记事本 ++ 准备了一个以值 0xFF 开头的文件-阅读该值效果很好,但是dest.put(source.get());在那种特定情况下不会。如何在 C++ 中使用(有符号的)半字节 [用于负差异] 和数字的二进制表示?顺便说一句,在 file.put() 中使用负数会导致奇怪的行为,因为写入的是 2 个字节而不是 1 个字节。这是我的代码,希望您能理解我的问题,非常感谢您的帮助

int lastValue = s.get();
d.put((char)lastValue);
char highNibble = 0;
bool nibbleSet = false;
int diff = 0;
for (int c = s.get(); c != -1; c = s.get()) {
    diff = (char)((unsigned char)c - (unsigned char)lastValue);
    if (abs(diff) > 7) {
        if (nibbleSet) {
            d.put(highNibble << 4 | 8);
            d.put((char)c);
            nibbleSet = false;
        }
        else {
            cout << (8 << 4 | (c & 0xF0) >> 4) << endl;
            d.put(8 << 4 | (c & 0xF0) >> 4);
            highNibble = c & 0x0F;
            nibbleSet = true;
        }
    }
    else {
        if (nibbleSet) {
            d.put(((char)highNibble << 4) & 0xF0 | ((char)diff) & 0x0F);
            nibbleSet = false;
        }
        else {
            highNibble = (char)diff;
            nibbleSet = true;
        }
    }
    lastValue = c;
}
4

0 回答 0