写二进制文件很奇怪的行为

时间:2014-05-30 06:39:05

标签: c++ ostream

输出二进制数据时,我遇到了一个非常令人困惑的问题。我正在编写一个采用ASCII文件格式的模型转换器,并将值转换为二进制。解析文件后,我以二进制形式写出值。一切都运行良好,一点点,然后事情变得奇怪。

正在输出的数据块如下所示:

struct vertex_t
{
    glm::vec2 texcoord;
    unsigned short weight_index_start;
    unsigned char weight_count;
};

这是有问题的二进制数据块,在#符号后面有一个人类可读的值。

00 00 80 3F # 1.000
AA AA AA 3E # 0.333
00 00       # 0
01          # 1

00 00 40 3F # 0.750
AA AA AA 3E # 0.333
01 00       # 1
01          # 1

00 00 40 3F # 0.750
00 00 00 00 # 0.000
02 00       # 2
01          # 1

...

一切看起来都很膨胀,直到第11个元素出现奇怪的事情......

00 00 00 3F # 0.500
AA AA AA 3E # 0.333
09 00       # 9
01          # 1

FE FF 7F 39 # 2.4x10^-4
AA AA 2A 3F # 0.666
0D          # 13 (why is this here?!)
0A 00       # 10
01          # 1

00 00 40 3F # 0.75
00 00 80 3F # 1.0
0B 00       # 11
01          # 1

正如您所看到的,0D写在结构的中间是没有明显原因的。以下是导出此结构的相关代码块:

for (const auto& vertex : mesh.vertices)
{
    ostream.write(reinterpret_cast<const char*>(&vertex.texcoord.x), sizeof(vertex.texcoord.x));
    ostream.write(reinterpret_cast<const char*>(&vertex.texcoord.y), sizeof(vertex.texcoord.y));
    ostream.write(reinterpret_cast<const char*>(&vertex.weight_index_start), sizeof(vertex.weight_index_start));
    ostream.write(reinterpret_cast<const char*>(&vertex.weight_count), sizeof(vertex.weight_count));
}

我不知道这是怎么发生的,但也许我错过了什么。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:3)

好像你正在将马车和换行推送到文件中。

OD : Carriage return
0A : NL line feed, New line

请参阅http://www.asciitable.com/

上的ASCII表

尝试使用ios :: binary paramater打开文件

示例:

fstream output("myfile.data", ios::out | ios::binary);

希望这有帮助!

答案 1 :(得分:1)

您不会显示您是如何编写数据的。一般来说, 但是,如果输出格式不是文本格式,则必须 以二进制模式打开文件;看起来好像 你是在Windows系统上,并没有做到这一点。二进制 值0x0A对应'\n',如果文件未打开 在二进制模式下,这将转换为依赖于系统 新的线路指标 - 在Windows下(可能大多数其他 非Unix系统),到两个字节序列0x0D,0x0A。

除非您的输出格式是文本,否则您必须打开该文件 二进制模式,在读取和写入时。 (经常 被遗忘的,充满了&#34; C&#34;区域;否则,可能会有 代码翻译。

使用写入方法来更新您的更新:这不会 输出 您保证以后能够阅读的任何内容。 (该 需要一个reinterpret_cast应该给你提示。)如果 您只是将太大的数据集溢出到磁盘上,以便重新读取 以后通过相同的过程,罚款(假设结构 只包含整数,浮点和枚举类型)。 在所有其他情况下,您需要定义二进制格式(或使用 已定义的一个,如XDR),将输出格式化为它,和 在输入上解析它。 (以完全便携的方式做到这一点 浮点数显然是非平凡的。另一方面, 大多数应用程序不需要完全可移植性,如果是 二进制格式基于IEEE和所有目标系统 使用IEEE,你通常可以解释这个位 浮点的模式为适当大小的无符号 int,读写这个。)