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

缓冲区读数据解决办法

2013-12-05 
缓冲区读数据原始文本文件:头ver:1signature:CUCtype:1no:1resv:0seq:8length:55数据:int1,1 int1,0 datet

缓冲区读数据
原始文本文件:
头  
ver:1
signature:CUC
type:1
no:1
resv:0
seq:8
length:55

数据:
int1,1 
int1,0 
datetime,2013-11-27 15:00:00    #时间采用UTC格式
datetime,2013-11-27 17:00:00
int1,1 
int1,4
ipv4,192.168.23.39
int2,50001
int1,1 
str,admin123
str,12345678
int4,60
生成对应的二进制文件(十六进制表示)
00000000h: 00 43 55 43 01 00 01 00 00 00 00 08 00 00 00 37
00000010h: 01 00 52 95 98 70 52 98 B4 90 01 04 C0 A8 17 27
00000020h: C3 51 01 61 64 6D 69 6E 31 32 33 31 32 33 34 35 
00000030h: 36 37 38 00 00 00 3C
现在要将二进制文件读出还原成文本文件。头部可以用结构体,但数据部分不行,要一项一项的读,
在缓冲区怎么才能读出来?
#pragma pack(1)
typedef struct _tUcHdr
{
    UINT1 ver;
    UINT1 proto_sig[3];
    UINT1 mess_type;
    UINT2 mess_No;
    UINT1 resv;
    UINT4 mess_sq_No;
    UINT4 mess_len;    
    //UINT1 data[0];
}UcHdr;
#pragma pack()
void para_policy_file(void)
{
    FILE *fd; 
    char buf[1024] = {0};
    char *pbuf = NULL;
    UcHdr *uchdr;  
    fd = fopen(filename,"rb");
    
    if(fd == NULL)
    {
        printf("open file error!\n");
        exit(1);
    }
    


    fread(buf, 1, 1024, fd);
    pbuf = buf;
    uchdr = (UcHdr *)pbuf;
    
    printf("ver:%d\n",uchdr->ver);    
    printf("proto_sig:");
    printf("%c",uchdr->proto_sig[0]);
    printf("%c",uchdr->proto_sig[1]);
    printf("%c\n",uchdr->proto_sig[2]);
    printf("mess_type:%d\n",uchdr->mess_type);
    printf("mess_No:%d\n",ntohs(uchdr->mess_No));
    printf("resv:%d\n",uchdr->resv);
    printf("mess_sq_No:%d\n",ntohl(uchdr->mess_sq_No));
    printf("mess_len:%d\n",ntohl(uchdr->mess_len));

    pbuf = (char *)pbuf + sizeof(UcHdr);

    *******这里数据部分怎么处理????
    fclose(fd);
} 文件读写
[解决办法]
用fgetc一个字节一个字节的分析处理。
[解决办法]
效率低不低取决于你的协议,局部来说你也可以一次取出几K,分析完了再读取几K这样来提升效率。

引用:
Quote: 引用:

用fgetc一个字节一个字节的分析处理。



好像不行哦!!!!!貌似这效率也蛮低的。

[解决办法]
很简单啊,准备一个std::string,然后parse发现数据不够就再读一些进来啊,parse完了erase掉继续啊。
[解决办法]
我是来看看解答的
[解决办法]
//头
//ver:1
//signature:CUC
//type:1
//no:1
//resv:0
//seq:8
//length:55
//数据:
//int1,1
//int1,0
//datetime,2013-11-27 15:00:00
//datetime,2013-11-29 23:36:48
//int1,1
//int1,4
//ipv4,192.168.23.39
//int2,50001
//int1,1
//str,admin123
//str,12345678
//int4,60
//生成对应的二进制文件(十六进制表示)b.bin:
//00000000h: 00 43 55 43 01 00 01 00 00 00 00 08 00 00 00 37
//00000010h: 01 00 52 95 98 70 52 98 B4 90 01 04 C0 A8 17 27
//00000020h: C3 51 01 61 64 6D 69 6E 31 32 33 31 32 33 34 35
//00000030h: 36 37 38 00 00 00 3C
#pragma comment(lib,"ws2_32")
#include <stdio.h>
#include <time.h>


#include <winsock2.h>
#pragma pack(push,1)
struct _H {
    char  ver;
    char  signature[3];
    char  type;
    short no;
    char  resv;
    int   seq;
    int   length;
} h;
struct _D {
    char           int1_0;
    char           int1_1;
    int            datetime_0;
    int            datetime_1;
    char           int1_2;
    char           int1_3;
    unsigned char  ipv4[4];
    unsigned short int2_0;
    char           int1_4;
    char           str_0[8];
    char           str_1[8];
    int            int4_0;
} d;
#pragma pack(pop)
FILE *f;
char *UTC(int t) {
    static char s[80];
    time_t tt;

    tt=(time_t)htonl(t);
    strftime(s,80,"%Y-%m-%d %H:%M:%S",localtime(&tt));
    return s;
}
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);
    fread(&d,sizeof(struct _D),1,f);
    fclose(f);
    printf("ver:%d\n"          ,h.ver);
    printf("signature:%.3s\n"  ,h.signature);
    printf("type:%d\n"         ,h.type);
    printf("no:%hd\n"          ,ntohs(h.no));
    printf("resv2:%d\n"        ,h.resv);
    printf("seq:%d\n"          ,ntohl(h.seq));
    printf("length:%d\n"       ,ntohl(h.length));
    printf("int1_0,%d\n"       ,d.int1_0);
    printf("int1_1,%d\n"       ,d.int1_1);
    printf("datetime_0,%s\n"   ,UTC(d.datetime_0));
    printf("datetime_1,%s\n"   ,UTC(d.datetime_1));
    printf("int1_2,%d\n"       ,d.int1_2);
    printf("int1_3,%d\n"       ,d.int1_3);
    printf("ipv4,%d.%d.%d.%d\n",d.ipv4[0],d.ipv4[1],d.ipv4[2],d.ipv4[3]);
    printf("int2_0,%hu\n"      ,ntohs(d.int2_0));
    printf("int1_4,%d\n"       ,d.int1_4);
    printf("str_0,%.8s\n"      ,d.str_0);
    printf("str_1,%.8s\n"      ,d.str_1);
    printf("int4_0,%d\n"       ,ntohl(d.int4_0));
    return 0;
}
//ver:0
//signature:CUC
//type:1
//no:1
//resv2:0
//seq:8
//length:55
//int1_0,1
//int1_1,0
//datetime_0,2013-11-27 15:00:00
//datetime_1,2013-11-29 23:36:48
//int1_2,1
//int1_3,4
//ipv4,192.168.23.39
//int2_0,50001
//int1_4,1
//str_0,admin123
//str_1,12345678
//int4_0,60
//


[解决办法]
电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址;
人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

[解决办法]
缓冲区读数据解决办法
//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
//


[解决办法]
string是对象,不是一段内存,不适合放在struct中。
[解决办法]

[解决办法]

但考虑到内存,,你这显然会浪费啊!

人为什么要长阑尾?
[解决办法]
//使用动态分配
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>


int i,L;
char *p;
void main() {
    for (i=0;i<20000;i++) {
        L=rand();
        p=malloc(L);
        if (NULL==p) {
            printf("malloc error!\n");
            continue;
        }
        memset(p,0,L);
        free(p);
    }
}
//不使用动态分配
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAXLEN 30000
int i,L;
char buf[MAXLEN];
char *p;
void main() {
    p=&buf[0];
    for (i=0;i<20000;i++) {
        L=rand();
        if (L>MAXLEN) {
            printf("L>MAXLEN==%d, ignore spilth.\n",MAXLEN);
            L=MAXLEN;
        }
        memset(p,0,L);
    }
}


个人倾向不使用动态分配。
[解决办法]
缓冲区读数据解决办法
[解决办法]
struct _D {
     short int2_0;
     short int2_1;
     char  int1_0;
     int   int4_0;
     char  int1_1;
     unsigned char  str_0_len;//前面加unsigned使其取值范围0..255而不是-128..127
     char  str_0[257];
} d[2];
[解决办法]

热点排行
Bad Request.