«Правильный» способ извлечь int из двоичного файла с прямым порядком байтов в c ++ - PullRequest
1 голос
/ 18 ноября 2011

У меня есть двоичный файл в формате с прямым порядком байтов, из которого я получаю 2-битные и 4-битные целочисленные данные. Машина, на которой я работаю, имеет младший порядок.

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

int myInt;

ifstream dataFile(dataFileLocation, ios::in | ios::binary);
dataFile.seekg(99, ios::beg);  //Pull data starting at byte 100;

//For 4-byte value:
char chunk[4];
dataFile.read(chunk, 4);
myInt = (int)(chunk[0] << 24 | chunk[1] << 16 | chunk[2] << 8 | chunk[3]);

//For 2-byte value:
char chunk[2];
dataFile.read(chunk, 4);
myInt = (int)(chunk[0] << 8 | chunk[1]);

Кажется, что это работает нормально для 2-байтовых данных, но дает, как мне кажется, неправильные значения для 4-байтовых данных. Я читал о htonl (), но из того, что я прочитал, это не умный способ добиться гибкости.

1 Ответ

4 голосов
/ 19 ноября 2011

Используйте только беззнаковые целочисленные типы, и все будет в порядке:

unsigned char buf[4];
infile.read(reinterpret_cast<char*>(buf), 4);

unsigned int b4 = (buf[0] << 24) + ... + (buf[3]);
unsigned int b2 = (buf[0] << 8) + (buf[1]);

Сдвиг включает в себя продвижение типов и неопределенные расширения знака (учитывая характер реализации char). По сути, вы всегда хотите, чтобы при манипулировании битами все было без знака.

...