#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
функцию. Это должно работать на любой машине, на которой вы компилируете код.