user-0 提问: 怎么用c语言解析二进制文件

回复:
user: user-0
content: typedef struct _tUcData {     UINT1 Bind_Action;     UINT1 User_Type;     UINT1 UName_len;     UINT1 UName[********UName_len];     UINT2 Mess_Num;     UINT1 Mess_Type;     UINT1 Mess_No; }UcData;   上面打星号的地方我要用前面的UName_len变量，应该怎么处理？？

user: user-0
content: 呵呵，，这是uc报文头的结构，，这是规定好的。。

user: user-1
content: #pragma pack(push, 1) typedef struct  _xxx{   unsigned char ver:4;   unsigned char resv1:4;   char signature[3];   unsigned char type;   .... }xxx, *pxxx; #pragma pack(pop)  ver是4位，resv1也是4位，两个加起来才是1字节.至于ver在前还是resv1在前，我已经不想再纠结了，自己跑一下试试，错了再换一下

user: user-2
content: 引用 9 楼 sai_johnny 的回复:[quote=引用 7 楼 ForestDB 的回复:] 分清1和'1' 用struct，注意padding 注意大小端，基本就这样了。 不明白他的二进制文件第一个字节为什么是0x01....[/quote] 这里的char表示8byte整数的意思，而不是指character。 注意分清1和'1'，看看ASCII。

user: user-3
content: 引用 3 楼 u012889234 的回复:再问下，为什么会出现大小端的转换？ 好像看错问题了，大小端的转换的是因为编码的格式不同啊，比如下图： 如果是不同的cpu上对于0x1234解释也是不同的，所以必须考虑大小端问题

user: user-3
content: 引用 3 楼 u012889234 的回复:再问下，为什么会出现大小端的转换？ 大小端由CPU决定，Intel的普通PC的CPU都是小端的。如果是arm或者服务器上可能会接触到两种CPU。  大端的符号位在首位，所以方便判断。而且我好像记得TCP/IP的报文规定是大端的，所以大端的机器方便接收。 小端的机器，偏移地址为0的地方提取最低位的字节，因为地址偏移和字节数是一对 一的关系，多重精度的数学函数就相对地容易写了。  总之各有各的好处。

user: user-4
content: 引用 7 楼 ForestDB 的回复:分清1和'1' 用struct，注意padding 注意大小端，基本就这样了。 不明白他的二进制文件第一个字节为什么是0x01....

user: user-4
content: 引用 6 楼 u012889234 的回复:ver 占的是4位， resv1也是占4位。他们一起才是一个字节。。所以不会是31 为啥是占4位呢。。。不是声明了char ver么？ 然后把第一个字节0x01读到了ver中。

user: user-5
content: //ver:1 //resv1:0 //signature:CUC //type:69 //no:5 //resv2:0 //seq:4 //length:56 //int2,1 //int2,2 //int1,1 //int4,30 //int1,1 //int1,7 //str,beijing //int2,1 //int2,4 //int1,1 //int4,60 //int1,1 //int1,7 //str,tianjin //int4,80 //二进制文件b.bin是: //00000000h: 01 43 55 43 45 00 05 00 00 00 00 04 00 00 00 38 //00000010h: 00 01 00 02 01 00 00 00 1E 01 07 62 65 69 6A 69 //00000020h: 6E 67 00 01 00 04 01 00 00 00 3C 01 07 74 69 61 //00000030h: 6E 6A 69 6E 00 00 00 50 #pragma comment(lib,"ws2_32") #include <stdio.h> #include <stdlib.h> #include <winsock2.h> #pragma pack(push,1) struct _H {     char  ver; //  char  resv1;     char  signature[3];     char  type;     short no;     char  resv2;     int   seq;     int   length; } h; struct _D {     short int2_0;     short int2_1;     char  int1_0;     int   int4_0;     char  int1_1;     char  str_0_len;     char  str_0[257]; } d[2]; int   t,i,n; #pragma pack(pop) FILE *f; int main() {     f=fopen("b.bin","rb");     if (NULL==f) {         printf("Can not open file b.bin!\n");         return 1;     }     fread(&h,sizeof(struct _H),1,f);     i=0;     while (1) {         if (1!=fread(&d[i],sizeof(struct _D)-257,1,f)) break;         fread(d[i].str_0,d[i].str_0_len,1,f);         d[i].str_0[d[i].str_0_len]=0;         i++;         if (i>=2) break;     }     n=i;     fread(&t,sizeof(int),1,f);     fclose(f);     printf("ver:%d\n"        ,h.ver);     printf("resv1:0\n");     printf("signature:%.3s\n",h.signature);     printf("type:%d\n"       ,h.type);     printf("no:%hd\n"        ,ntohs(h.no));     printf("resv2:%d\n"      ,h.resv2);     printf("seq:%d\n"        ,ntohl(h.seq));     printf("length:%d\n"     ,ntohl(h.length));     for (i=0;i<n;i++) {         printf("%d int2_0:%hd\n"  ,i,ntohs(d[i].int2_0));         printf("%d int2_1:%hd\n"  ,i,ntohs(d[i].int2_1));         printf("%d int1_0:%d\n"   ,i,d[i].int1_0);         printf("%d int4_0:%d\n"   ,i,ntohl(d[i].int4_0));         printf("%d int1_1:%d\n"   ,i,d[i].int1_1);         printf("%d str_0_len:%d\n",i,d[i].str_0_len);         printf("%d str_0:%s\n"    ,i,d[i].str_0);     }     printf("t:%d\n"     ,ntohl(t));     return 0; } //ver:1 //resv1:0 //signature:CUC //type:69 //no:5 //resv2:0 //seq:4 //length:56 //0 int2_0:1 //0 int2_1:2 //0 int1_0:1 //0 int4_0:30 //0 int1_1:1 //0 str_0_len:7 //0 str_0:beijing //1 int2_0:1 //1 int2_1:4 //1 int1_0:1 //1 int4_0:60 //1 int1_1:1 //1 str_0_len:7 //1 str_0:tianjin //t:80 //

user: user-2
content: 分清1和'1' 用struct，注意padding 注意大小端，基本就这样了。

user: user-0
content: ver 占的是4位， resv1也是占4位。他们一起才是一个字节。。所以不会是31

user: user-0
content: 很好，，，已解决问题！感谢！！！！！！！

user: user-4
content: 引用 1 楼 zhao4zhong1 的回复: //00000000h: 01 43 55 43 45 00 05 00 00 00 00 04 00 00 00 38  大端机器上可省略ntohs和ntohl 我想不明白，他的二进制文件第一个字节为啥会是01，而不是31。。。。

user: user-0
content: 再问下，为什么会出现大小端的转换？

user: user-6
content: 看你每个数据是多少位，一一对应的读应该就可以了。 比如说你的Ver是占以为，那么01就代表的Ver。

user: user-5
content: //ver:1 //resv1:0 //signature:CUC //type:69 //no:5 //resv2:0 //seq:4 //length:56 //int2,1 //int2,2 //int1,1 //int4,30 //int1,1 //int1,7 //str,beijing //int2,1 //int2,4 //int1,1 //int4,60 //int1,1 //int1,7 //str,tianjin //int4,80 //二进制文件b.bin是: //00000000h: 01 43 55 43 45 00 05 00 00 00 00 04 00 00 00 38 //00000010h: 00 01 00 02 01 00 00 00 1E 01 07 62 65 69 6A 69 //00000020h: 6E 67 00 01 00 04 01 00 00 00 3C 01 07 74 69 61 //00000030h: 6E 6A 69 6E 00 00 00 50 #pragma comment(lib,"ws2_32") #include <stdio.h> #include <winsock2.h> #pragma pack(push,1) struct _D {     char  ver; //  char  resv1;     char  signature[3];     char  type;     short no;     char  resv2;     int   seq;     int   length;     short int2_0;     short int2_1;     char  int1_0;     int   int4_0;     char  int1_1;     char  int1_2;     char  str_0[7];     short int2_2;     short int2_3;     char  int1_3;     int   int4_1;     char  int1_4;     char  int1_5;     char  str_1[7];     int   int4_2; } d; #pragma pack(pop) FILE *f; int main() {     f=fopen("b.bin","rb");     if (NULL==f) {         printf("Can not open file b.bin!\n");         return 1;     }     fread(&d,sizeof(struct _D),1,f);     fclose(f);     printf("ver:%d\n"        ,d.ver);     printf("resv1:0\n");     printf("signature:%.3s\n",d.signature);     printf("type:%d\n"       ,d.type);     printf("no:%hd\n"        ,ntohs(d.no));     printf("resv2:%d\n"      ,d.resv2);     printf("seq:%d\n"        ,ntohl(d.seq));     printf("length:%d\n"     ,ntohl(d.length));     printf("int2_0:%hd\n"    ,ntohs(d.int2_0));     printf("int2_1:%hd\n"    ,ntohs(d.int2_1));     printf("int1_0:%d\n"     ,d.int1_0);     printf("int4_0:%d\n"     ,ntohl(d.int4_0));     printf("int1_1:%d\n"     ,d.int1_1);     printf("int1_2:%d\n"     ,d.int1_2);     printf("str_0:%.7s\n"    ,d.str_0);     printf("int2_2:%hd\n"    ,ntohs(d.int2_2));     printf("int2_3:%hd\n"    ,ntohs(d.int2_3));     printf("int1_3:%d\n"     ,d.int1_3);     printf("int4_1:%d\n"     ,ntohl(d.int4_1));     printf("int1_4:%d\n"     ,d.int1_4);     printf("int1_5:%d\n"     ,d.int1_5);     printf("str_1:%.7s\n"    ,d.str_1);     printf("int4_2:%d\n"     ,ntohl(d.int4_2));     return 0; } //ver:1 //resv1:0 //signature:CUC //type:69 //no:5 //resv2:0 //seq:4 //length:56 //int2_0:1 //int2_1:2 //int1_0:1 //int4_0:30 //int1_1:1 //int1_2:7 //str_0:beijing //int2_2:1 //int2_3:4 //int1_3:1 //int4_1:60 //int1_4:1 //int1_5:7 //str_1:tianjin //int4_2:80 //  大端机器上可省略ntohs和ntohl