| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 688 人关注过本帖
标题:大侠们帮看看这个解包程序怎么写比较好
只看楼主 加入收藏
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
结帖率:77.78%
收藏
已结贴  问题点数:15 回复次数:8 
大侠们帮看看这个解包程序怎么写比较好
以前搞运维,现在马上要搞开发了,不得不突击学C,没有组包解包的经验,所以自己给自己乱出了个题目,
主要是练习解包的:
写一个函数,传入一个很长的字符串fred2362109861100000117534501041980022810111234567ggg123456789012


作为参数,根据配置文件进行处理,返回一个数组,每个元素内容为一个字符串。
例如配置文件为:
name|4|fred
age|2|23
acount|19|6210986110000011753
paper_no|18|450104198002281011
sn|7|1234567
other|3|ggg
other1|12|123456789012
说明:配置文件第一、三列内容只是注释作用,第三列可以不写,函数要处理的是2列,例如:
第一行的4表明要截取传入的字符串的1-4个字符作为第一个字段name的值,
第二行的2表明要截取传入的字符串的5-6个字符作为第二个字段age的值,
第三行的19表明要截取传入的字符串的7-25个字符作为第三个字段acount的值,
...

函数返回结果为一个数组,内容为:a[0]="fred" a[1]="23" a[2]="6210986110000011753"依次类推,
配置文件的内容是可以自己随意修改的,不一定按案例,但处理规则要按本题要求,行数可以增加,而函数就是根据配置文件去处理传入的字符串。
程序接收函数返回后,在屏幕这样显示:
解包:
位元1:fred
位元2:23
位元3:6210986110000011753
...
位元n:.......
说白了,这个程序一个用途就是用来检验组包对不对的。
希望高手们能多提供自己的方案,以便小弟学习一下。


[ 本帖最后由 khaz 于 2011-4-27 10:32 编辑 ]
搜索更多相关主题的帖子: 字符串 元素 
2011-04-26 23:47
boxinchao
Rank: 4
等 级:业余侠客
帖 子:51
专家分:231
注 册:2011-4-13
收藏
得分:3 
你这不是给自己出的题目吗?还是先提出自己的方案吧
2011-04-26 23:51
cacker
该用户已被删除
收藏
得分:3 
提示: 作者被禁止或删除 内容自动屏蔽
2011-04-27 00:13
voidx
Rank: 12Rank: 12Rank: 12
来 自:邯郸
等 级:火箭侠
帖 子:1250
专家分:3538
注 册:2011-4-7
收藏
得分:3 
楼主去看看 sscanf() 的 reference 就明白了,做这个太简单了
2011-04-27 01:03
gongyaping
Rank: 4
来 自:广东肇庆怀集
等 级:业余侠客
帖 子:174
专家分:257
注 册:2010-8-1
收藏
得分:3 
学习了。
2011-04-27 06:21
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
收藏
得分:0 
以下是引用voidx在2011-4-27 01:03:53的发言:

楼主去看看 sscanf() 的 reference 就明白了,做这个太简单了
谢谢你的意见。
2011-04-27 10:26
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
收藏
得分:0 
以下是引用cacker在2011-4-27 00:13:32的发言:

既然配置文件不是告诉  每个字段的长度了  那你就往出取就完了   看了两次你这题目   貌似你已经把规则定好了

那就实现规则就哦了     

fred2362109861100000117534501041980022810111234567ggg123456789012

我的理解是  你根据配置文件name|4  这里的4是关键  从配置文件第一行开始计算 匹配符||  匹配符中间的值为要取的长度

然后就循环吧   直到找不到||匹配符   函数就返回


不知道楼主说的是不是这个意思

如果是这样。那很简单   

你这不能算是解包    你这包应该都已经解完了   最多最多你这题目属于   解包之后  类型已经知道  属于具体的逻辑处理函数
解包应该有很多解释吧 你说的是狭义的 我说的是广义的
就好比我自己在电报规定1234=“我”字 1236="是"字,拿到我的密码本才能解码,不然你不知道1234代表什么意思。这里就是解码 翻译的意思。
同理,我配置文件格式也是解释这段字符串用的,没有这个配置文件 你是不知道字符串含义的。这个也可以理解为解包的。
现在不是说我无法做这个题目 我是想看看有什么更好的方法和思路可以借鉴的 像voidx 就提出了自己的思路(虽然字很少 但是回复很有用)。
2011-04-27 10:31
cacker
该用户已被删除
收藏
得分:0 
提示: 作者被禁止或删除 内容自动屏蔽
2011-04-28 00:12
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
收藏
得分:0 
我已经自己写好了。也许称为拆包程序更恰当。发给大家看看有什么要改进的。我修改了一下配置文件,第三列只是注释作用:
[view@localhost pkg]$cat pkg.ini
主帐号/卡号|19|6210986110000011876
交易处理码|6|100210
渠道标识码|2|03
流水号|8|45100011
本地时间|6|123448
本地日期|8|20110428
清算日期|8|20110428
交易标志|8|11110111
服务点进入方式|3|001
服务点条件代码|2|02
手续费1|8|00000500
手续费2|8|00000000
交易系统代码|11|45010100123
发信系统代码|11|45010100121
第二磁道数据|37|6210986110000011876=62109861100000118
第三磁道数据|104|996210986110000011876=6210986110000011876=6210986110000011876=6210986110000011876=62109861100000118760000
系统检索号|12|123456789012
响应码|2|00
终端标识码|8|00000007
交易局代码/受卡方标识码|15|010062100012345
存折印刷号|10|2010122702
个人识别号(PIN)|64|1111111111222222222233333333334444444444555555555566666666661234
安全控制信息|16|0000000000111111
证件信息|22|4501041987092310101111
[view@localhost pkg]$cat pkg.ini
主帐号/卡号|19|6210986110000011876
交易处理码|6|100210
渠道标识码|2|03
流水号|8|45100011
本地时间|6|123448
本地日期|8|20110428
清算日期|8|20110428
交易标志|8|11110111
服务点进入方式|3|001
服务点条件代码|2|02
手续费1|8|00000500
手续费2|8|00000000
交易系统代码|11|45010100123
发信系统代码|11|45010100121
第二磁道数据|37|6210986110000011876=62109861100000118
第三磁道数据|104|996210986110000011876=6210986110000011876=6210986110000011876=6210986110000011876=62109861100000118760000
系统检索号|12|123456789012
响应码|2|00
终端标识码|8|00000007
交易局代码/受卡方标识码|15|010062100012345
存折印刷号|10|2010122702
个人识别号(PIN)|64|1111111111222222222233333333334444444444555555555566666666661234
安全控制信息|16|0000000000111111
证件信息|22|4501041987092310101111
[view@localhost pkg]$cat pkg.c
#include<stdio.h>
#include<stdlib.h>

int main(int argc,char *argv[]){
        if(argc!=2){
        fprintf(stderr,"usage: %s string\n",argv[0]);
        exit(1);
        }
        FILE *f,*f1;
        int line;
        f=popen("wc -l pkg.ini|awk '{print $1}'","r");
        if(f==NULL){
        fprintf(stderr,"popen() error!\n");
        exit(1);
        }
        fscanf(f,"%d",&line);
        int i;
        char *strtmp=(char*)malloc(2048);
        char **ptr=(char**)malloc(4*line);
        char **fmt=(char**)malloc(5*line);
        char **btr=(char**)malloc(1000*line);
        for(i=0;i<line;i++){
        ptr[i]=(char *)malloc(3);
        fmt[i]=(char *)malloc(5);
        btr[i]=(char *)malloc(1000);
        }

        f1=fopen("pkg.ini","r");
        if(f1==NULL){
        fprintf(stderr,"pkg.ini:file not found!\n");
        exit(1);
        }


        i=0;
        while(fscanf(f1,"%*[^|]|%[^|]|",ptr[i])!=EOF){
        i++;
        }

        strcpy(strtmp,argv[1]);
        for(i=0;i<line;i++){
        sprintf(fmt[i],"%%%ss",ptr[i]);
        sscanf(strtmp,fmt[i],btr[i]);
        fprintf(stdout,"位元%d:(长度%s):\t%s\n",i,ptr[i],btr[i]);
        strtmp+=atoi(ptr[i]);
        }
        fprintf(stdout,"超长部分:%s\n",strtmp);

        exit(0);
}
[view@localhost pkg]$./pkg 6210986110000011876100210034510001112344820110428201104281111011100102000005000000000045010100123450101001216210986110000011876=62109861100000118996210986110000011876=6210986110000011876=6210986110000011876=6210986110000011876=621098611000001187600001234567890120000000070100621000123452010122702111111111122222222223333333333444444444455555555556666666666123400000000001111114501041987092310101111
位元0:(长度19): 6210986110000011876
位元1:(长度6):  100210
位元2:(长度2):  03
位元3:(长度8):  45100011
位元4:(长度6):  123448
位元5:(长度8):  20110428
位元6:(长度8):  20110428
位元7:(长度8):  11110111
位元8:(长度3):  001
位元9:(长度2):  02
位元10:(长度8): 00000500
位元11:(长度8): 00000000
位元12:(长度11):        45010100123
位元13:(长度11):        45010100121
位元14:(长度37):        6210986110000011876=62109861100000118
位元15:(长度104):       996210986110000011876=6210986110000011876=6210986110000011876=6210986110000011876=6210986110000011876000
位元16:(长度12):        012345678901
位元17:(长度2): 20
位元18:(长度8): 00000007
位元19:(长度15):        010062100012345
位元20:(长度10):        2010122702
位元21:(长度64):        1111111111222222222233333333334444444444555555555566666666661234
位元22:(长度16):        0000000000111111
位元23:(长度22):        4501041987092310101111
超长部分:



[ 本帖最后由 khaz 于 2011-4-29 09:01 编辑 ]
2011-04-28 22:55
快速回复:大侠们帮看看这个解包程序怎么写比较好
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.055736 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved