包含二进制字符的char数组中的Endian-ness

时间:2011-10-05 10:22:33

标签: c++ endianness

我正在构建一些代码来读取RIFF wav文件而且我遇到了一些奇怪的事情。

文件头的前4个字节是 big-endian ascii编码中的单词RIFF:

   0x5249 0x4646

我使用以下方法阅读了第一个元素:

char *fileID = new char[4];
filestream.read(fileID,4);

当我将此内容写入屏幕时,结果符合预期:

std::cout << fileID << std::endl;
>>  RIFF

现在,接下来的4个字节给出了文件的大小,但至关重要的是它们是 little-endian

所以,我写一个小函数来翻转字节,基于一个联合:

int flip4bytes(char* input){

   union flip {int flip_int; char flip_char[4];};

   flip.flip_char[0] = input[3];
   flip.flip_char[1] = input[2];
   flip.flip_char[2] = input[1];
   flip.flip_char[3] = input[0];

   return flip.flip_int;

 }

这对我来说很好,除非我调用它,返回的值是完全错误的。有趣的是,以下代码(字节反转!)正常工作:

int flip4bytes(char* input){

   union flip {int flip_int; char flip_char[4];};

   flip.flip_char[0] = input[0];
   flip.flip_char[1] = input[1];
   flip.flip_char[2] = input[2];
   flip.flip_char[3] = input[3];

   return flip.flip_int;

 }

这让我很困惑。联盟是否以某种方式为我改变了字节?!如果没有,如何正确转换为int而不被反转?

我认为这里有一些端点,我对此无知......

2 个答案:

答案 0 :(得分:5)

你只是在一个小端机器上,“RIFF”字符串只是一个字符串,因此既不是小端也不是大端,而只是一系列字符。你不需要在little-endian机器上反转字节,但是你需要在big-endian上运行。

答案 1 :(得分:2)

您需要了解机器的 endianess #include <sys/param.h>会帮助您做到这一点。

你也可以使用网络字节顺序大的事实(如果我的记忆正确地为我服务 - 你需要检查)。在这种情况下,转换为大结尾并使用ntohs函数。这应该适用于您编译代码的任何机器。