Я предполагаю, что это проблема с порядком байтов.т.е. вы помещаете байты 42
и 4D
в ваше значение short
.Но ваша система имеет прямой порядок байтов (у меня может быть неправильное имя), который фактически читает байты (в многобайтовом целочисленном типе) слева направо, а не справа налево.
Демонстрируется в этом коде:
#include <stdio.h>
int main()
{
union {
short sval;
unsigned char bval[2];
} udata;
udata.sval = 1;
printf( "DEC[%5hu] HEX[%04hx] BYTES[%02hhx][%02hhx]\n"
, udata.sval, udata.sval, udata.bval[0], udata.bval[1] );
udata.sval = 0x424d;
printf( "DEC[%5hu] HEX[%04hx] BYTES[%02hhx][%02hhx]\n"
, udata.sval, udata.sval, udata.bval[0], udata.bval[1] );
udata.sval = 0x4d42;
printf( "DEC[%5hu] HEX[%04hx] BYTES[%02hhx][%02hhx]\n"
, udata.sval, udata.sval, udata.bval[0], udata.bval[1] );
return 0;
}
Дает следующий вывод
DEC[ 1] HEX[0001] BYTES[01][00]
DEC[16973] HEX[424d] BYTES[4d][42]
DEC[19778] HEX[4d42] BYTES[42][4d]
Так что, если вы хотите быть переносимым, вам нужно будет определить порядковый номер вашей системы, а затем, при необходимости, выполнить перестановку байтов.В интернете будет множество примеров обмена байтами.
Следующий вопрос:
Я спрашиваю только потому, что размер моего файла равен 3, а не196662
Это связано с проблемами выравнивания памяти.196662 - это байты 36 00 03 00
, а 3 - это байты 03 00 00 00
.Большинству систем нужны такие типы, как int
и т. Д., Чтобы их нельзя было разделить на несколько блоков памяти words
.Интуитивно вы думаете, что ваша структура размещена в памяти как:
Offset
short magic_number; 00 - 01
int file_size; 02 - 05
short reserved_bytes[2]; 06 - 09
int data_offset; 0A - 0D
НО в 32-битной системе, что означает, что files_size
имеет 2 байта в том же word
, что и magic_number
, и два байта вследующий word
.Большинство компиляторов этого не допустят, поэтому способ размещения структуры в памяти на самом деле выглядит следующим образом:
short magic_number; 00 - 01
<<unused padding>> 02 - 03
int file_size; 04 - 07
short reserved_bytes[2]; 08 - 0B
int data_offset; 0C - 0F
Итак, когда вы читаете свой поток байтов в 36 00
, вы попадаете в область заполнения, котораяоставляет ваш file_size как 03 00 00 00
.Теперь, если вы использовали fwrite
для создания этих данных, все должно быть в порядке, так как байты заполнения были бы записаны.Но если ваш ввод всегда будет в указанном вами формате, нецелесообразно читать всю структуру как единое целое с символом fread.Вместо этого вам нужно будет прочитать каждый из элементов в отдельности.