我目前正在尝试更深入地了解文件格式。
我有一个 3D 文件格式(在这种情况下为 U3D)的规范,我想尝试实现它。没什么大不了的,只是为了学习效果。
我的问题很早就从需要定义的类型开始。我必须定义不同的整数(8 位、16 位、32 位无符号和有符号),然后需要将它们转换为十六进制,然后再将其写入文件。
我如何定义这些类型,因为我不能只创建一个 I16 即?我的另一个问题是如何将 I16 转换为 8 位的十六进制数(即 0001 0001)。
十六进制只是一个数字的表示。是否将数字解释为二进制、十进制、十六进制、八进制等取决于您。在 C++ 中,您支持十进制、十六进制和八进制表示,但它们都以相同的方式存储。
例子:
int x = 0x1;
int y = 1;
assert(x == y);
文件格式可能希望您以正常的二进制格式存储文件。我认为文件格式不希望将十六进制数字作为可读的文本字符串。如果确实如此,那么您可以使用 std::hex 为您进行转换。(例如file << hex << number;
:)
如果文件格式涉及将超过 1 个字节的类型写入文件,那么请注意架构的字节顺序。这意味着您首先或最后存储多字节类型的最高有效字节。
在文件格式规范中,向您展示二进制文件应如何查找文件的给定部分是很常见的。不过不要将此与实际将二进制数字存储为字符串相混淆。同样,他们有时会通过以十六进制指定其外观来为此提供快捷方式。在大多数情况下,它们实际上并不意味着文本字符串。
C++ 中最小的可寻址单元char
是 1 个字节。如果要在该字节内设置位,则需要使用按位运算符&
and |
。位运算符的教程很多,这里就不详细介绍了。
如果包含<stdint.h>
,您将获得以下类型:
uint8_t
int16_t
uint32_t
首先,让我明白。整数以十六进制格式以文本形式存储在文件中,没有前缀 0x?
然后,使用以下语法:
fprintf(fp, "%08x", 数字);
将 0abc1234 写入文件。
至于“定义不同的整数(8 位、16 位、32 位无符号和有符号)”,除非您自己滚动并为它们进行伴随的数学运算,否则您应该坚持系统提供的类型。有关可用的 typedef,请参见 stdint.h,例如 int32_t。