如何诊断保存和加载位向量 (std::vector<bool>) 的异常行为?

How to diagnose bizarre behavior of saving and loading a bit vector (std::vector<bool>)?

我正在编写一个一次性实用程序来编辑游戏的单色位图格式。 8x8 单色精灵有 0x10000 "slots"。我将每个 8x8 精灵存储在八个字节中,每个代表一条水平线的开像素或关像素。

当我在插槽 0 到 24 中绘制字符 A 到 Y 时,一切都很好。它们都在保存和加载的往返过程中幸存下来,具有完全相同的位模式。但是随后,槽位 25 中的 Z 绘图在往返过程中丢失了其中一条水平线。更糟糕的是,无论 Z 在哪里,都会发生这种情况,并将其下方的所有行向上移动!我注意到 25 之后插槽中其他模式的其他类似行为。

我的代码看起来一次只检查一个像素,所以我不知道如何诊断这个问题。

据我所知,问题是删除了 0x0C 字节。这似乎不太可能是 ASCII 表单提要(^L'\f')字符的问题。

我没有找到任何 Google 关于缺少换页字符的结果,所以我猜这是我的代码中的错误。

这是保存程序和加载程序。 (这不是我编写发布或生产代码的方式!)

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <SDL.h>
#include <stdint.h>

static std::vector<bool> bitmap(0x400000, 0);

void save(const char *path)
{
    std::ofstream f(path, std::ios::binary);
    for (int i = 0; i < 0x10000; ++i)
    for (int j = 0; j < 8; ++j) {
        uint8_t byte = 0;
        for (int k = 0; k < 8; ++k)
            byte |= bitmap[8 * (8 * i + j) + k] << (7 - k);
        f << byte;
    }
    f.close();
    std::cout << "Wrote charmap to " << path << std::endl;
}

void load(const char *path)
{
    std::ifstream f(path, std::ios::binary);
    for (int i = 0; i < 0x10000; ++i)
    for (int j = 0; j < 8; ++j) {
        uint8_t byte;
        f >> byte;
        for (int k = 0; k < 8; ++k)
            bitmap[8 * (8 * i + j) + k] = !!(byte & (1 << (7 - k)));
    }
    f.close();
    std::cout << "Read charmap from " << path << std::endl;
}

int main(int argc, char *argv[]) { /* ... snip ... */ }

我希望保留 0x0C 字节,但它们已被删除。感谢指点!

在处理二进制文件时,不要使用格式化 流操作符(f << ...;f >> ...;),即使它们是以二进制模式打开的。你不想要 格式化 input/output,你想要字节 written/read as-is。请改用 ofstream::write()ifstream::read() 方法,例如:

//f << byte;
f.write(reinterpret_cast<char*>(&byte), sizeof(byte));
//f >> byte;
f.read(reinterpret_cast<char*>(&byte), sizeof(byte));