从 C++ 中的大端二进制文件中检索 int 的“正确”方法

The*_*eOx 2 c++ binary int endianness

我有一个 big-endian 格式的二进制文件,我正在从中检索 2 位和 4 位整数数据。我正在运行的机器是小端的。

有没有人对从已知格式的二进制文件中提取整数数据并即时切换字节序有任何建议或最佳实践?我不确定我当前的解决方案是否正确:

int myInt;

ifstream dataFile(dataFileLocation, ios::in | ios::binary);
dataFile.seekg(99, ios::beg);  //Pull data starting at byte 100;

//For 4-byte value:
char chunk[4];
dataFile.read(chunk, 4);
myInt = (int)(chunk[0] << 24 | chunk[1] << 16 | chunk[2] << 8 | chunk[3]);

//For 2-byte value:
char chunk[2];
dataFile.read(chunk, 4);
myInt = (int)(chunk[0] << 8 | chunk[1]);
Run Code Online (Sandbox Code Playgroud)

这似乎适用于 2 字节数据,但在 4 字节数据上给出了我认为不正确的值。我已经阅读了有关 htonl() 的内容,但从我所读到的内容来看,这并不是实现灵活性的明智之举。

Ker*_* SB 5

只使用无符号整数类型,你会没事的:

unsigned char buf[4];
infile.read(reinterpret_cast<char*>(buf), 4);

unsigned int b4 = (buf[0] << 24) + ... + (buf[3]);
unsigned int b2 = (buf[0] << 8) + (buf[1]);
Run Code Online (Sandbox Code Playgroud)

移位涉及类型提升和不定符号扩展(考虑到 的实现定义性质char)。基本上,在操作位时,您总是希望所有内容都是无符号的。

  • @bames53:我喜欢认为 C++ 只处理 *values*,而不处理 *representations*。(我认为作者同意。)因此,我尽可能地更喜欢“代数”运算而不是按位运算。这与代数字符类型(`signed char`/`unsigned char`)的使用密切相关,而不是“平台单位”`char` 类型。这个观点还强调字节序纯粹是外部表示的属性,而不是*值*的属性。 (2认同)