我正在构建一些代码来读取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个字节给出了文件的大小,但至关重要的是它们是小端的 .
所以,我根据一个联合写了一个小函数来翻转字节:
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而不被反转?
我认为这里有一些关于endian-ness的方面我不知道......
2 回答
你只是在一个小端机器上,“RIFF”字符串只是一个字符串,因此既不是小端也不是大端,而只是一系列字符 . 您不需要在little-endian机器上反转字节,但是在big-endian上操作时需要 .
您需要了解机器的endianess .
#include <sys/param.h>
将帮助您做到这一点 .你也可以使用网络字节顺序大的事实(如果我的记忆正确地为我服务 - 你需要检查) . 在这种情况下转换为大结束并使用
ntohs
函数 . 这应该适用于您编译代码的任何机器 .