我认为这是一个endian问题。即您将字节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
在同一word
2个字节为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读取整个结构是不合适的。相反,您需要分别阅读每个元素。
...面包乱用你的叮咬顺序?你尝试啃食吗? – Mehrdad 2011-12-19 03:55:18
你的标题不是'fread'而不是'bread'吗? – buruzaemon 2011-12-19 03:55:39
对不起。我仍然需要正确使用Lions Auto。我修好了 – 2011-12-19 04:00:05