2015-11-03 2 views
2

Что я хочу сделать: прочитайте серию из 4 байтов, например. 00000000 00000011 00000001 00000011 (это случайный пример) из двоичного файла и представить его как целое в моей программе. Каков наилучший способ сделать это?Байты для целого из двоичного файла

EDIT РЕШЕНИЕ Я просмотрел эту часть спецификации для формата PNG файлов here, надеюсь, что это полезно для всех, кто считает этот вопрос.

Я экспериментирую с форматом изображения PNG, и у меня возникают проблемы с извлечением 4-байтового числа. Мне удалось открыть и распечатать двоичное представление файла, поэтому я знаю, что данные, с которыми я работаю, не повреждены или не искажены.

Я рассмотрел такие вопросы, как Reading 16-bit integers from binary file c++, и 32-битный эквивалент (-ы), но я не могу различить, читают ли они целые числа, которые находятся в двоичном файле, например. 00000000 72 00000000 или чтение байтов как целых чисел, что и является моей целью.

В качестве примера, первые четыре байта первого блока являются 00000000 00000000 00000000 00001101 или 13.

Следуя примеру такие вопросы, как один из приведенных выше, это должно == 13:

int test; 
img.read((char*) &test, sizeof(test)); 

пока он выводит 218103808

Я также попытался подход с использованием объединения с массивом символов и целым числом элемент данных, и получил тот же выход 218103808

также, в моей системе sizeof(int) равно 4

И, наконец, чтобы быть уверенным, что это не был неправильный PNG (что я не уверен), я использовал gimp для импорта, а затем экспортировал его как новый файл, поэтому изначально был создан в моей системе.

EDIT

Как я уже говорил, после seekg(8) следующие четыре байта 00000000 00000000 00000000 00001101, но когда я решил проверить функцию read с помощью

bitset<32> num; 
img.read((char*) &num, sizeof(int)); 

выводит 00001101 00000000 00000000 00000000 Я просто перепутал этим часть, здесь. Это как если бы байты здесь были отменены. И эта строка байтов приравнивает к 218103808

Любое понимание будет оценено

+0

Для общего представления о том, как начать работу, вы можете посмотреть на мои старые ответы. http://stackoverflow.com/a/5762648/179910 –

+0

Спасибо, это очень полезно. Я немного теряю, почему я получаю значение '218103808', упомянутое в моем редактировании. Я вижу это в вашей функции проверки заголовка. Я знаю, что это означает длину, которая равна 13, но почему она искалечена этим другим числом? Еще раз спасибо –

+0

Я думаю, вы в замешательстве о ноториале. Первый абзац https://en.wikipedia.org/wiki/Endianness должен вас подвести. –

ответ

3

Обратите внимание, что 218103808 является 0x0D000000 в шестнадцатеричном формате. Возможно, вы захотите прочитать о Endianess

Это означает, что данные, которые вы читаете, находятся в формате большого конца, в то время как ваша платформа использует мало endian.

В основном вам нужно поменять местами 4 байта, (и вы, вероятно, хотите использовать целые числа без знака), так что вы получите 0x0000000D, (13 десятичное), которые вы можете сделать так:

#define BSWAPUINT(x) ((((x) & 0x000000ff) << 24) |\ 
         (((x) & 0x0000ff00) << 8) |\ 
         (((x) & 0x00ff0000) >> 8) |\ 
         (((x) & 0xff000000) >> 24)) 
unsigned int test; 
img.read((char*) &test, sizeof(test)); 
test = BSWAPUINT(test); 

Приведенный выше код работает только в том случае, если код работает на платформе с маленькой платформой.

Чтобы ваш код не зависит от того, ваша платформа большой или маленький обратный порядок байт можно собрать байты в целое число самостоятельно, при условии, что вы знаете формат данных большой байтов, вы можете сделать:

unsigned char buf[4]; 
unsigned int test; 
img.read((char*) &test, sizeof(test)); 
test = (unsigned int)buf[0] << 24; 
test |= buf[1] << 16; 
test |= buf[2] << 8; 
test |= buf[3]; 

Или, на системах UNIX вы можете #include <arpa/inet.h> и использовать ntohl()

test = ntohl(test); 

(Работа с данными таким образом, вы также лучше использовать такие типы, как uint32_t вместо INT/неподписанных Int, от stdint.h)

+0

Это, безусловно, так. Я не могу поверить, что я упустил из виду концепцию PNG, когда я исследовал формат файла. Благодаря тонну –