Endian-ness в массиве char, содержащем двоичные символы - PullRequest
0 голосов
/ 05 октября 2011

Я создаю некоторый код для чтения wav-файла RIFF и натолкнулся на что-то странное.

Первые 4 байта заголовка файла - это слово RIFF в big-endian ascii coding:

   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 ]

5 голосов
/ 05 октября 2011

Вы просто находитесь на машине с прямым порядком байтов, и строка "RIFF" - это просто строка и, следовательно, ни байты с прямым порядком байтов, но и просто последовательность символов.Вам не нужно инвертировать байты на машине с прямым порядком байтов, но это необходимо при работе с байтами с прямым порядком байтов.

2 голосов
/ 05 октября 2011

Вам необходимо указать порядковый номер вашей машины.#include <sys/param.h> поможет вам в этом.

Вы также можете использовать тот факт, что сетевой порядок байтов имеет большой конец (если моя память обслуживает меня правильно - вам нужно проверить).В этом случае конвертируйте в большой конец и используйте функцию ntohs.Это должно работать на любой машине, на которой вы компилируете код.

...