c++字节读取问题

C++ Reading bytes Problem

本文关键字:问题 读取 字节 c++      更新时间:2023-10-16

我有这个问题,我不知道如果是预期的,事情是这样的:

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

struct
{
    char
    char
    char
    char
    unsigned int
}

但问题是当unsigned int被填充时,似乎在读取流中交换了字节,例如,如果文件包含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;
    }
}

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

正如您所发现的,可移植序列化可能是一件麻烦事。您不需要写入和读取结构,而是需要以规范化格式(网络字节顺序是常见的)单独序列化每个属性。然后,当您反序列化字节时,返回正确。

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

使用特定于平台的选项:

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

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

如果你想跨平台,你必须测试它的尾序和pragma支持的问题。

只是为了给蛋糕添加一点糖霜!

你也必须处理32位和64位的问题。

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

你可能需要考虑大/小端序。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

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