免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: yxw030826
打印 上一主题 下一主题

[C] 请教结构体指针 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2010-04-03 23:28 |只看该作者
报文是有分隔符的啊,怎么能直接存进去,还会加上头部信息,比如长度,校验信息等

论坛徽章:
0
12 [报告]
发表于 2010-04-03 23:33 |只看该作者
回复 8# yxw030826


    晕

memmove这个函数不会用啊?

你的报文存进去,那么怎么取出来也知道哪

比如struct  xxx you_xxx,

char pkg[1000000]; //恶搞一下

memmove(pkg, &you_xxx, sizeof you_xxx);

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
13 [报告]
发表于 2010-04-03 23:46 |只看该作者
本帖最后由 flw 于 2010-04-03 23:47 编辑

呵呵,问这个问题的,都是不会封装的。
这一类问题,两大招:
1,用宏来完成一个成员的打包(每种类型的成员一个宏)
2,用函数来完成整个业务的打包(每个业务一个或一对函数)

如果想做的比这更好一些,
可以自己设计一些描述语言,
比如我曾经设计过的:
例子1(2001 年作品)
  1. field_01, 1; /* 扩展BITMAP标记 */
  2. field_02, 5; /* 业务号 */
  3. field_03, 5; /* 交易代码 */
  4. field_04, 5; /* 原交易代码 */
  5. field_05, 1; /* 银行帐号类型 */
  6. field_06,20; /* 银行帐号 */
  7. field_07, 1; /* 业务单位帐号类型 */
  8. field_08,20; /* 业务单位帐号 */
  9. field_09,20; /* 业务单位银行单位帐号 */
  10. field_10,12; /* 交易金额 */
  11. field_11,12; /* 银行帐号余额 */
  12. field_12,12; /* 业务单位帐号余额 */
  13. field_13, 5; /* 业务单位编号 */
  14. field_14, 6; /* 交易时间 */
  15. field_15, 8; /* 交易日期 */
  16. field_16, 8; /* 有效期 */
  17. field_17, 8; /* 交易起始日期 Reserved */
  18. field_18, 8; /* 交易结束日期 Reserved */
  19. field_19, 8; /* 交费起始日期 */
  20. field_20, 8; /* 交费结束日期 Reserved */
  21. field_21, 8; /* 打印票据日期 */
  22. field_22,10; /* BIS系统流水 */
  23. field_23,10; /* 银行流水 */
  24. field_24,10; /* 业务单位流水 */
  25. field_25,10; /* 终端流水 */
  26. field_26,10; /* 银行终端流水 */
  27. field_27,10; /* 查询流水序号 */
  28. field_28,12; /* 票据号 */
  29. field_29, 2; /* 银行号 */
  30. field_30, 2; /* 包类型 Reserved */
  31. field_31, 2; /* 设备标识包类型 Reserved */
  32. field_32,30; /* 终端识别号 Reserved */
  33. field_33,20; /* 身份证号 */
  34. field_35,37; /* 二磁道数据 */
  35. field_36,104; /* 三磁道数据 */
  36. field_37, 3; /* 返回码 */
  37. field_38,10; /* 商户号 */
  38. field_39,10; /* 终端号 */
  39. field_40, 6; /* 操作员号 */
  40. field_41, 6; /* 操作员密码 */
  41. field_42, 6; /* 操作员新密码 */
  42. field_43, 6; /* 新操作员号 */
  43. field_44,10; /* 打印商户号 */
  44. field_45,10; /* 银行终端商户号 */
  45. field_46,10; /* 银行终端终端号 */
  46. field_47, 6; /* 银行终端操作员号 */
  47. field_48, 1; /* 银行密码方式 */
  48. field_49, 8; /* 银行密码 */
  49. field_50, 1; /* 业务单位密码方式 */
  50. field_51, 8; /* 业务单位密码 */
  51. field_52,128; /* 附加费/手续费/对帐数据 */
  52. field_53,80; /* 附加文件名 */
  53. field_54,16; /* MKEY */
  54. field_55,16; /* WKEY */
  55. field_56,16; /* MACKEY */
  56. field_57,10; /* 原BIS系统流水 */
  57. field_58,30; /* ErrMsg */
  58. field_59, 1; /* 打印标志 */
  59. field_60, 1; /* 交易批量标志 */
  60. field_61, 1; /* 交易处理标志 */
  61. field_62,80; /* 备用字段 */
  62. field_63,600; /* 附加字段 */
  63. field_64, 8; /* MAC校验码 */

  64. qsdm        11        0
  65. jydm        5        11
  66. yhdm        3        16
  67. zjzh        21        19
  68. szdm        9        40
  69. shdm        11        49
  70. yhzh        21        60
  71. sfzh        21        81                                // 用作流水号
  72. czmm        7        102
  73. zjmm        7        109
  74. qsxh        7        116
  75. yhxh        7        123
  76. zzje        13        130
  77. fsrq        9        143
  78. fssj        7        152
  79. cjsj        7        159
  80. fqbz        1        166
  81. sbbh        11        167
  82. gydm        7        178
  83. jfhm        5        185
  84. jmac        9        190

  85. 4021=QSQD:qsdm,field_06.qsdm,field_06.
  86. 4022=QSQT:qsdm,field_13.qsdm,field_13.
  87. 1006=ZZKH:qsdm,field_13;yhzh,field_06;zjzh,field_08;fssj,field_14;fsrq,field_15;gydm,field_40.qsdm,field_13;yhzh,field_06;zjzh,field_08;fssj,field_14;fsrq,field_15.
  88. 1056=ZZXH:qsdm,field_13;yhzh,field_06;zjzh,field_08;fssj,field_14;fsrq,field_15;gydm,field_40.qsdm,field_13;yhzh,field_06;zjzh,field_08;fssj,field_14;fsrq,field_15.
  89. 1001=BTOS:qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;gydm,field_40.qsdm,field_13;yhzh,field_06;zjzh,field_08;zzje,field_10;----,field_11;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.
  90. 1002=STOB:qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;gydm,field_40.qsdm,field_13;yhzh,field_06;zjzh,field_08;zzje,field_10;----,field_11;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.
  91. 1101=BSCZ:qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.
  92. 1102=SBCZ:qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.
  93. 3042=MXZZ:qsdm,field_13;fssj,field_14;fsrq,field_15.qsdm,field_13;zrje,field_06;zcje,field_08;----,field_14;fsrq,field_15;zrbs,field_23;zcbs,field_24.

  94. QSQD=4021:qsdm,field_13.qsdm,field_13.
  95. QSQT=4022:qsdm,field_13.qsdm,field_13.
  96. ZZKH=1006:qsdm,field_13;yhzh,field_06;zjzh,field_08;fssj,field_14;fsrq,field_15;gydm,field_40.qsdm,field_13;yhzh,field_06;zjzh,field_08;fssj,field_14;fsrq,field_15.
  97. ZZXH=1056:qsdm,field_13;yhzh,field_06;zjzh,field_08;fssj,field_14;fsrq,field_15;gydm,field_40.qsdm,field_13;yhzh,field_06;zjzh,field_08;fssj,field_14;fsrq,field_15.
  98. YHYE=2004:qsdm,field_13;yhzh,field_06;zjzh,field_08;fssj,field_14;fsrq,field_15;gydm,field_40.qsdm,field_13;yhzh,field_06;zjzh,field_08;zzje,field_11;fssj,field_14;fsrq,field_15.
  99. BTOS=1001:qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;gydm,field_40.qsdm,field_13;yhzh,field_06;zjzh,field_08;zzje,field_10;----,field_11;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.
  100. STOB=1002:qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;gydm,field_40.qsdm,field_13;yhzh,field_06;zjzh,field_08;zzje,field_10;----,field_11;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.
  101. BSCZ=1101:qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.
  102. SBCZ=1102:qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.qsdm,field_13;zjzh,field_08;zzje,field_10;fssj,field_14;fsrq,field_15;yhxh,field_22;gydm,field_40.
  103. MXZZ=3042:qsdm,field_13;fssj,field_14;fsrq,field_15.qsdm,field_13;zrje,field_06;zcje,field_08;----,field_14;fsrq,field_15;zrbs,field_23;zcbs,field_24.
复制代码

例子2(2007 年作品):
  1. # define CIS101_FORMAT_STR "30A|CONSIGNDATE<8n          \
  2.                             0BC|TRNSCTID<8n             \
  3.                             CC5|PUTEXCHNGNO<12n         \
  4.                             59C|CACCOUNT<32x            \
  5.                             59A|CACCNAME<60g            \
  6.                             D21|RCVEXCHNGNO<12n         \
  7.                             D23|DACCOUNT<32x            \
  8.                             D22|DACCNAME<60g            \
  9.                             32A|AMOUNT<18x              \
  10.                             D32|VCHTYPE<2n              \
  11.                             D01|VCHCODE<12n             \
  12.                             D35|SIGNDATE<8n             \
  13.                             D36|PROMPTPAYDATE<8n        \
  14.                            *D51|GENVCHRPWD<20x          \
  15.                            *33H|VCHRAMOUNT<15n          \
  16.                            *D61|VCHRLIFE<8n             \
  17.                            *D62|PAYCODE<20x             \
  18.                            *D63|DEALCOMPACTCODE<20x     \
  19.                            *D64|LASTPAYDATE<8n          \
  20.                            *D65|PAYBANKEXCHGCODE<12n    \
  21.                            *D66|PAYMAN<60g              \
  22.                            *D37|PURPOSE<60g             \
  23.                            *D38|MEMO<120g               \
  24.                            *D41|BWRITINGTIMES<2n        \
  25.                            *D42|BWRITINGLIST<1024g      \
  26.                            *D34|DEALDATE<8n             \
  27.                            *BS6|RTNRECEIPTLIMITE<8n     \
  28.                            *BS4|RESENDFLAG<1n           \
  29.                            *DA0<2n                      \
  30.                            *DA9<1800x                   \
  31.                             72E|FILENAME_F<10240000I    \
  32.                             72F|FILENAME_B<10240000I"

  33. # define CIS305_FORMAT_STR "30A|CONSIGNDATE<8n          \
  34.                             CJA|ORIQUERYDATE<8n         \
  35.                             01C|QUERYNODE<12n           \
  36.                             0BB|ORIQUERYNO<8n           \
  37.                             02D|ORIMSG_TYPE<3n          \
  38.                             051|ORICONSIGNDATE<8n       \
  39.                             005|ORITRNSCTID<8n          \
  40.                            *D73|PUTSCNTRECTIME<14n      \
  41.                            *D74|PUTSCNTTRNSMTSTA<2n     \
  42.                            *DB1|PUTSCNTBNSSTA<2n        \
  43.                            *DB4|PUTSCNTRCPTSTA<10n      \
  44.                            *D75|CCNTRECTIME<14n         \
  45.                            *D76|CCNTTRNSMTSTA<2n        \
  46.                            *DB2|CCNTBNSSTA<2n           \
  47.                            *DB5|CCNTRCPTSTA<10n         \
  48.                            *D77|RECSCNTRECTIME<14n      \
  49.                            *D78|RECSCNTTRNSMTSTA<2n     \
  50.                            *DB3|RECSCNTBNSSTA<2n        \
  51.                            *DB6|RECSCNTRCPTSTA<10n"

  52. # define CIS410_SUB_FMT1   "code:12n                    \
  53.                             type:2n                     \
  54.                             center:4n                   \
  55.                             city:4n                     \
  56.                             name:60g                    \
  57.                             short:20g                   \
  58.                             addr:60g                    \
  59.                             tel:20x                     \
  60.                             contact:16g                 \
  61.                             postcode:6n                 \
  62.                             email:30x                   \
  63.                             date:8n                     \
  64.                             action:1n                   \
  65.                             memo:60g"
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
14 [报告]
发表于 2010-04-03 23:49 |只看该作者
基本上,如何把程序员从繁琐而又容易出错的打包解包中解脱出来,
直接面对描述性的报文格式而不是一对 memcpy 或者长长的 sprintf 参数,
这是金融、电信行业的一个课题。

所以现在许多打包解包的代码都是程序生成的,
用可视化的编辑器一拖,输入界面出来了,打包解包的代码也出来了,呈现的报表也出来了。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
15 [报告]
发表于 2010-04-03 23:51 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
16 [报告]
发表于 2010-04-03 23:53 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
17 [报告]
发表于 2010-04-04 00:27 |只看该作者
学习了,谢谢指教

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
18 [报告]
发表于 2010-04-05 12:05 |只看该作者
本帖最后由 yulihua49 于 2010-04-05 13:45 编辑
有一个结构体
struct info
{
    char     a[2+1];
    char     b[2+1];
    double  amt;
    int  ...
yxw030826 发表于 2010-04-03 16:46



   你这个要求比较奇怪,但我能理解。一般情况是不行的。
如果一定要实现,方法是比较复杂的:
为结构建立模板.
模板本身也是一个结构,它说明一个字段的类型、长度、名称、格式、属性等信息。
这个结构形成数组,逐项说明某结构的各个字段。
然后可以对模板数组进行下标循环访问,通过模板访问数据结构。
比如:

  1. 定义模板结构:
  2. typedef struct {
  3.              int type;
  4.              int len;
  5.              char *name;
  6.              char *format;
  7.              int offset;
  8. }T_PkgType;

  9. //for type
  10. #define CH_CHAR 1
  11. #define CH_SHORT 2
  12. #define CH_INT 3
  13. #define CH_LONG 4
  14. #define CH_DOUBLE 8
  15. #define CH_STRUCT 10
  16. //定义模板
  17. T_PkgType sacc_tpl[]={
  18.       {CH_CHAR ,2+1,"acc",0,-1},
  19.       {CH_INT,sizeof(int),"acc_type"},
  20.    {CH_DOUBLE,sizeof(double),"amt"},  
  21.     {-1,0,0,0} //结束符  
  22. };

  23. T_PkgType info_tpl[]={
  24.     {CH_CHAR,2+1,"a",0,-1},   
  25.     {CH_CHAR,2+1,"b"},
  26.     {CH_DOUBLE,sizeof(double),"amt"},  
  27.     {CH_INT,sizeof(int),"c"},
  28.     {CH_STRUCT,-1,"acc",(char *)sacc_tpl},
  29.     {-1,0,0,0} //结束符  
  30. };

  31. 先对模板预处理,设定offset:
  32.     i=set_offset(sacc_tpl);
  33.       info_tpl[4].len=sacc_tpl[i].offset;//确定sacc结构长度;
  34.       j=set_offset(info_tpl);

  35. 然后就可以循环处理了:
  36. T_PkgType *tpl;
  37. char *record=(char *)&info;

  38. for(tpl=info_tpl;tpl->type>=0;tpl++) {
  39.        char *addr=record+tpl->offset;
  40.         switch(tpl->type) {
  41.         case CH_CHAR:
  42. ......
  43.         case CH_INT:
  44. .......
  45.         case CH_DOUBLE:
  46. .......
  47.         case CH_STRUCT:
  48. T_PkgType *tp;
  49.                 for(tp=(T_PkgType *)tpl->format;tp->type>=0;tp++) {
  50.                     char * data_addr1= addr+tp->offset;
  51.                         switch(tp->type) {
  52.                         case CH_CHAR:
  53.    ......
  54. ......
  55.                         default:break;
  56.                        }
  57.                  }
  58.                  break;
  59.         default: break;
  60.         }
复制代码
思路与楼上类似,这个方案稍加修改就是一个通用的工具,用于处理各种结构问题。

set_offset()在这里有,在该文最后:
http://space.itpub.net/8804348/viewspace-478471

论坛徽章:
0
19 [报告]
发表于 2010-04-05 16:59 |只看该作者
为什么要写

char     a[2+1];

而不写

char     a[3];

有什么特别的意思吗?

论坛徽章:
0
20 [报告]
发表于 2010-04-05 22:39 |只看该作者
没什么特别的含义,+1 表示还有一个'\0'
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP