我试图读取二进制文件。问题是该文件的创建者没有时间将数据结构正确地对齐到它们的自然边界,并且所有内容都紧密排列。这使得使用C ++结构很难读取数据。
有没有办法迫使struct
紧缩?
示例:
struct {
short a;
int b;
}
上述结构为8个字节:short a
为2,填充为2,int b
为4。但是,在磁盘上,数据只有6个字节(没有2个字节的填充用于对齐)
请注意实际的数据结构是数千个字节和许多字段,包括几个数组,因此我不希望单独读取每个字段。
答案 0 :(得分:29)
如果您正在使用GCC,则可以执行struct __attribute__ ((packed)) { short a; int b; }
在VC ++上,您可以执行#pragma pack(1)
。此选项为also supported by GCC。
#pragma pack(push, 1)
struct { short a; int b; }
#pragma pack(pop)
其他编译器可以选择在没有填充的情况下对结构进行紧密包装。
答案 1 :(得分:8)
您需要使用特定于编译器的非标准指令来指定1字节打包。比如在Windows下:
#pragma pack (push, 1)
问题是该文件的创建者没有时间正确 字节对齐数据结构,所有内容都紧凑。
实际上,设计师做了正确的事。填充是标准所说的可以应用的东西,但它没有说明在什么情况下应该应用多少填充。标准甚至没有说明一个字节中有多少位。尽管你可能会认为即使没有指定这些东西,它们在现代机器上仍然应该具有相同的合理价值,但事实并非如此。例如,在32位Windows机器上,填充可能是一回事,而在64位版本的Windows上则可能是其他东西。也许它会是一样的 - 这不是重点。关键是你不知道不同系统上的填充是什么。
因此,通过“紧紧包装”,开发人员尽其所能 - 使用一些包装,他可以合理地确定每个系统都能够理解。在这种情况下,通常理解的包装是在保存到磁盘或发送电线的结构中不使用填充。