c语言fread出现的奇怪异常

c语言fread出现的奇怪错误。
先上代码,想学习FAT文件系统,写了个函数读取BPB,但是使用fread读取结构体时,发现有个位置被跳过去了,在hexdump 中能看到该位置的数是 00  但是读取时貌似跳过了这个数。

#include <stdio.h>
#include "fat_struct.h"
int main()
{
int i;
struct BPB_ this_bpb;
FILE *fp;
fp=fopen("/dev/sdb4","rb");
if(fp!=NULL)
{
printf("Open success!\n");
}
printf("The File pointer is %p\n",fp);
fread(&this_bpb,sizeof(this_bpb),1,fp);
for(i=0;i<3;i++)
printf("Bs_jump=%x\n",this_bpb.Bs_jump[i]);
for(i=0;i<=10;i++)
{
printf("BPB_OEMName[%d]=%x\n",i,this_bpb.Bs_OEM[i]);
}
// printf("Bs_OEM=%s\n",this_bpb.Bs_OEM);
printf("BPB_BytsPerSec=%x\n",this_bpb.BPB_BytsPerSec);
printf("BPB_SecPerClus=%x\n",this_bpb.BPB_SecPerClus);
printf("BPB_RsvdSecCnt=%d\n",this_bpb.BPB_RsvdSecCnt);
printf("BPB_NumFATs=%d\n",this_bpb.BPB_NumFATs);
printf("BPB_RootEntCnt=%d\n",this_bpb.BPB_RootEntCnt);
printf("BPB_TotSec16=%d\n",this_bpb.BPB_TotSec16);
printf("BPB_Media=%x\n",this_bpb.BPB_Media);
printf("BPB_FATSz16=%d\n",this_bpb.BPB_FATSz16);
printf("BPB_SecPerTrk=%d\n",this_bpb.BPB_SecPerTrk);
printf("BPB_NumHeads=%d\n",this_bpb.BPB_NumHeads);
printf("BPB_HiddSec=%d\n",this_bpb.BPB_HiddSec);
printf("BPB_TotSec32=%d\n",this_bpb.BPB_TotSec32);



这是定义的结构体

struct BPB_{
unsigned char Bs_jump[3];
unsigned char Bs_OEM[8];
short int  BPB_BytsPerSec;
unsigned char BPB_SecPerClus;
short int  BPB_RsvdSecCnt;
unsigned char BPB_NumFATs;
short int  BPB_RootEntCnt;
short int BPB_TotSec16;
unsigned char BPB_Media;
short int  BPB_FATSz16;
short int  BPB_SecPerTrk;
short int  BPB_NumHeads;
unsigned int  BPB_HiddSec;
unsigned int  BPB_TotSec32;
};


------解决思路----------------------
仅供参考
#include <stdio.h>
#define field_offset(s,f) (int)(&(((struct s *)(0))->f))
struct AD  { int a; char b[13]; double c;};
#pragma pack(push)
#pragma pack(1)
struct A1  { int a; char b[13]; double c;};
#pragma pack(2)
struct A2  { int a; char b[13]; double c;};
#pragma pack(4)
struct A4  { int a; char b[13]; double c;};
#pragma pack(8)
struct A8  { int a; char b[13]; double c;};
#pragma pack(16)
struct A16 { int a; char b[13]; double c;};
#pragma pack(pop)
int main() {
    printf("AD.a %d\n",field_offset(AD,a));
    printf("AD.b %d\n",field_offset(AD,b));
    printf("AD.c %d\n",field_offset(AD,c));
    printf("\n");
    printf("A1.a %d\n",field_offset(A1,a));
    printf("A1.b %d\n",field_offset(A1,b));
    printf("A1.c %d\n",field_offset(A1,c));
    printf("\n");
    printf("A2.a %d\n",field_offset(A2,a));
    printf("A2.b %d\n",field_offset(A2,b));
    printf("A2.c %d\n",field_offset(A2,c));
    printf("\n");
    printf("A4.a %d\n",field_offset(A4,a));
    printf("A4.b %d\n",field_offset(A4,b));
    printf("A4.c %d\n",field_offset(A4,c));
    printf("\n");
    printf("A8.a %d\n",field_offset(A8,a));
    printf("A8.b %d\n",field_offset(A8,b));
    printf("A8.c %d\n",field_offset(A8,c));
    printf("\n");
    printf("A16.a %d\n",field_offset(A16,a));
    printf("A16.b %d\n",field_offset(A16,b));
    printf("A16.c %d\n",field_offset(A16,c));
    printf("\n");
    return 0;
}
//AD.a 0
//AD.b 4
//AD.c 24
//
//A1.a 0
//A1.b 4
//A1.c 17
//
//A2.a 0
//A2.b 4
//A2.c 18
//
//A4.a 0
//A4.b 4
//A4.c 20
//
//A8.a 0
//A8.b 4
//A8.c 24
//
//A16.a 0
//A16.b 4
//A16.c 24
//
//

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

不要把
fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待

fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待
弄混了