Порядковый номер в массиве символов, содержащем двоичные символы

#c #endianness

#c #порядковый номер

Вопрос:

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

Первые 4 байта заголовка файла — это слово RIFF в кодировке ascii с большим порядковым номером:

    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 без обращения вспять?

Я думаю, что здесь есть какой-то аспект порядкового номера, о котором я не знаю..

Комментарии:

1. Массив символов не имеет понятия порядкового номера. Это просто массив байтов, один за другим. Порядковый номер применяется только к типам, которые шире одного байта, таким как an int . Кроме того, вы имеете в виду char flip_char[4] в вашем объединении?

2. Я сделал да, отредактировал, чтобы отразить это. Спасибо

Ответ №1:

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

Ответ №2:

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

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