c ++规范化跨系统的数据大小

时间:2010-12-28 18:46:37

标签: c++ binaryfiles

我有一个包含三个变量的结构:两个无符号整数和一个unsigned char。根据我的理解,c ++ char总是1个字节,无论它在哪个操作系统上。其他数据类型也不能这样说。我正在寻找一种规范化POD的方法,这样当保存到二进制文件中时,生成的文件在编译代码的任何操作系统上都是可读的。

我通过添加#pragma来改变我的结构以使用1字节对齐,如下所示:

#pragma pack(push, 1) 
struct test
{
   int a;
}
#pragma pack(pop)

但这并不一定意味着int a在每个操作系统上只有4个字节,我不这么认为?有没有办法确保从我的代码中保存的文件始终可读?

4 个答案:

答案 0 :(得分:3)

您可以在std::int32_t中找到固定宽度的整数类型(例如std::uint16_t<cstdint>)。您的C ++标准库实现可能不包括<cstdint>(它不是当前C ++标准的一部分;它是C ++ 0x的一部分),在这种情况下Boost has an implementation应该适用于大多数平台。

请注意,除了其他方面,您仍然需要考虑字节序和对齐。如果你的代码需要在具有不同数字表示的平台上运行(例如,一个补码和两个补码),你也需要考虑它。

答案 1 :(得分:0)

如果您关注的是32位Windows,64位Windows,Linux(x86和AMD64)和Mac(x86,AMD64,PPC),那么它就更容易了。所有这些系统上的int总是32位。如果您可以允许丢弃PPC,它也将始终是小端。如果您需要支持big-endian系统,我建议使用ntohl / htonl以网络字节顺序存储数据。

答案 2 :(得分:0)

没有办法像这样编写二进制结构,并且任何系统都可以读取它。虽然您可以使用某些定义int32类型的库,但这并不能解决您的问题。

不同的处理器使用不同的字节顺序,可能需要不同的对齐方式。此外,填充是依赖于实现的。幸运的是,我所知道的所有当前处理器都使用二进制补码表示整数表示,而不是单补码或符号幅度,因此整数至少具有相同的二进制表示(模数字节顺序)。

#pragma可以是真正的可移植解决方案,因为它们是按定义实现定义的,并且您无法确定不同的编译器会将它们视为相同。有一些更多的说明符正在为下一个C ++标准工作,但它们在一段时间内不会那么常见。

您将要做的是使用类似struct的内容指定int32,然后将其分解为字节流并在另一端重新构建它。查找“序列化”。

答案 3 :(得分:0)

执行此操作的正确方法是以标准格式序列化数据。这样做有很多标准。为简单起见,CSV是一个(逗号分隔的变量)。如果您想要更高效的标准,请尝试使用XDR,或者在电信行业中使用的一种,ASN.1。