C ++读字节问题

时间:2011-07-26 18:56:52

标签: c++

我有这个问题,我不知道是否有所期待,这就是事情:

我正在尝试将文件中的字节加载到这样的结构中:

struct
{
    char
    char
    char
    char
    unsigned int
}

但问题是当unsigned int被填充时,似乎在读取流中字节被交换,e.x。如果文件包含0x45080000,则unsigned int将为0x84500000,这是错误的。

如果我改变了BYTE [4]的unsigned int,这可以“解决”,但不是我想要的。这是我用来从文件中读取的代码:

fopen_s( &mFile, "myFile.ext", "rb" );

if( mFile == NULL ) print( " **** E R R O R ! **** " );
else
{
    if( fread( &myStruct, sizeof( MY_Struct ), 1, myFile) != 1)
    {
        print( " **** E R R O R ! **** " );
        return 0;
    }
}

这是预期的行为还是我做错了什么?

此致

4 个答案:

答案 0 :(得分:3)

正如您所发现的,便携式序列化可能会很痛苦。您需要以规范化格式单独序列化每个属性(网络字节顺序很常见),而不是编写和读取结构。然后,当您反序列化时,字节会正确返回。

答案 1 :(得分:1)

单独序列化/反序列化每个字段(符合标准)或......

使用特定于平台的选项:

#pragma pack(push,1)
struct foo {
  // ...
};
#pragma pack(pop)

这将foo中的所有变量与1字节对齐对齐,因此它不适用于布尔值。

如果你打算跨平台,你将不得不测试它的地狱性和pragma支持的问题。

答案 2 :(得分:1)

只是为蛋糕添加一些结冰!

您还必须处理32位与64位问题。

一个非常好的包含文件是stdint.h(C99)。它定义了具有特定大小的类型,因此在切换字宽时可以减少问题。

答案 3 :(得分:0)

你可能需要考虑大/小端。 试试s.th.像这样:

#define BIG_ENDIAN
//#define LITTLE_ENDIAN
...
#ifdef BIG_ENDIAN

inline void writeMem32(uint8* buf, uint32 val)
{
    buf[0] = static_cast<uint8>(val >> 24);
    buf[1] = static_cast<uint8>(val >> 16);
    buf[2] = static_cast<uint8>(val >>  8);
    buf[3] = static_cast<uint8>(val >>  0);
}

inline uint32 readMem32(const uint8* buf)
{
    return ( ((*(buf+0)) << 24) | ((*(buf+1)) << 16) | ((*(buf+2)) << 8) | (*(buf+3)) );
}

#endif // BIG_ENDIAN

如果你在小端,字节顺序当然是不同的:)