首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

如何用c语言解析二进制文件

2013-11-30 
怎么用c语言解析二进制文件我的文本文件是:ver:1resv1:0signature:CUCtype:69no:5resv2:0seq:4length:56in

怎么用c语言解析二进制文件
我的文本文件是:
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
二进制文件是:
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
这怎么用c语言读取二进制文本的数据。。
给个思路啥的~~~ 解析二进制文件
[解决办法]

//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
[解决办法]
看你每个数据是多少位,一一对应的读应该就可以了。
比如说你的Ver是占以为,那么01就代表的Ver。
[解决办法]

[解决办法]
分清1和'1'
用struct,注意padding
注意大小端,基本就这样了。
[解决办法]

如果是不同的cpu上对于0x1234解释也是不同的,所以必须考虑大小端问题
[解决办法]
引用:
Quote: 引用:

分清1和'1'
用struct,注意padding
注意大小端,基本就这样了。

不明白他的二进制文件第一个字节为什么是0x01....

这里的char表示8byte整数的意思,而不是指character。
注意分清1和'1',看看ASCII。
[解决办法]
#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在前,我已经不想再纠结了,自己跑一下试试,错了再换一下
[解决办法]
//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
//

热点排行