高效率、灵活打印结构体串(C语言版)
来源:互联网 发布:网络数据传输流程 编辑:程序博客网 时间:2024/06/18 11:14
C语言中很多时候把结构体当做字符串使用。
例如一个简单的报文协议:
命令类型 4字节 //通信测试报文 “1001”
交易系统ID 2字节
版本号 10字节
MAC 8字节
数据 20字节
那么我们根据不同的报文定义结构体:
typedef struct { char TRXTYPE[TYPE_LEN]; char BUSID [BUSID_LEN]; char VER [VER_LEN]; char MAC[MAC_LEN]; char DATA[DATA_LEN];}TEST_S;
下面是定义结构体,然后赋值发送。
TEST_S test_s; spritf(test_s.TRXTYPE, "1001"); spritf(test_s.BUSID, "FF"); ………… //各种赋值 SendBuff(&test_s, sizeof(test_s)); //发送数据
---------------------------------------------------------------------------------
我们要如何打印这个结构体呢? 或者是接到的结构体
一种简单的做法是根据不同的报文 拼接打印。
比如打印测试报文:
void show1001(TEST_S *ptest_s){if(ptest_s == NULL) //可增加打印信息return ;//showPrintf 增加打印介绍符printf("TRXTYPE =[%s](%d)", showPrintf(ptest_s->TRXTYPE,TYPE_LEN) , TYPE_LEN);printf("BUSID =[%s](%d)", showPrintf(ptest_s->BUSID, BUSID_LEN) , BUSID_LEN); …………}
这种打印有很多坏处,如果想修改打印样式需要修改每个打印函数,需要写很多冗余的代码,效率低下容易出错。
-----------------------------------------------------------------------------------------------------------------------------------------------------------
下面介绍一种使用通用打印函数加结构体属性的打印方法(原创,但肯定有雷同)
除了结构体定义外,在定义一个结构体属性;
以上面的TEST_S结构体为例,结构体属性为:
/*************结构打印**************/typedef struct {intfield_len;//域长度charfield_name[STRU_FIELD_NAME_LEN];//域名字}FIELD_PRO;typedef struct {intfield_num;//域数量FIELD_PROfield_pro[STRU_MAX_NUM];//域属性}STRUCT_PUB_CONF;/*****定义test结构体属性****/STRUCT_PUB_CONF pri_1001_s ={5,{ { TYPE_LEN, TRXTYPE_NAME }, //自定义域名宏{ BUSID_LEN, BUSID_NAME}, { VER_LEN,VER_NAME},{ MAC_LEN,MAC_NAME},{ DATA_LEN,DATA_NAME}}};
每个需要打印的结构体只需要定义一个这样的结构体就可以打印了,是不是比每个结构体写一个打印函数(void show1001(TEST_S *ptest_s))简单呢!
事实证明效率非常高。
下面是实现的核心,统一打印函数。
/******************************************************************************** 函数名称 :PriStruct* 说明 :根据结构体属性,打印结构体内容* 输入参数 :in_s - 结构体串* struct_pub_conf - 结构体属性,记录域长度 名称等* 输出参数 : 打印结构体内容,可动态分配打印空间* 返回值 : 无* 修改历史 :* * 2015/11/18, lei.l create this function*******************************************************************************/void PriStruct(char *in_s, STRUCT_PUB_CONF *struct_pub_conf){inti = 0, index = 0, field_len = 0;intcalloc_flag = 0;char*pin_s = NULL;charfield_value[PRI_FIELD_DEL_LEN] = {0};char*pfield_value = NULL;char*pshow = NULL;FIELD_PRO*pfield_pro = NULL;if (in_s == NULL || struct_pub_conf == NULL){printf("PriStruct inparam error!\n");return ;}pin_s = in_s;//循环打印结构体for (i = 0; i < struct_pub_conf->field_num; i++){calloc_flag = 0;pfield_pro = (FIELD_PRO *)&struct_pub_conf->field_pro[i];//域长度大于默认的打印buff长度,根据实际大小分配空间 /*PRI_WIDHT_DEL * 3 是因为还要打印"() [] =" 等字符*/ if ((pfield_pro->field_len + PRI_WIDHT_DEL*3) >= PRI_FIELD_DEL_LEN){pfield_value = (char *)calloc(pfield_pro->field_len + PRI_WIDHT_DEL*3, 1);if (pfield_value == NULL){printf("PriStruct calloc error!\n");return ;}calloc_flag = 1;}else{ //打印域长度小于PRI_FIELD_DEL_LEN 256 则不分配堆空间,提高效率memset(field_value, 0, sizeof(field_value));pfield_value = field_value;}memset(pfield_value, ' ', PRI_WIDHT_DEL);//获取到域的名字memcpy(pfield_value, pfield_pro->field_name, strlen(pfield_pro->field_name));field_len = pfield_pro->field_len;index = strlen(pfield_value);pshow = showPrintf(pin_s, field_len);if (pshow == NULL){printf("PriStruct calloc error!");if (1 == calloc_flag){free(pfield_value);pfield_value = NULL;}return;}sprintf(&pfield_value[index], "=[%s](%d)\n", pshow, strlen(pshow));printf(pfield_value);//下个域值得起始位置pin_s += field_len;if ( 1 == calloc_flag ){free(pfield_value);pfield_value = NULL;}}return ;}项目实际使用效果:
/*打印结构体*/
PriStruct((char *)&Int_63Y0,&pri_63Y0_s);
输出:
2015-11-18 16:43:48.619 paycomponentsvrDlg.cpp:1696 [6516] TRXTYPE :[1001](4)2015-11-18 16:43:48.620 paycomponentsvrDlg.cpp:1696 [6516] MAC :[FC8B67A1](8)2015-11-18 16:43:48.622 paycomponentsvrDlg.cpp:1696 [6516] BUSISYSID :[EE](2)2015-11-18 16:43:48.624 paycomponentsvrDlg.cpp:1696 [6516] BUSITERNO :[110000050080](12)2015-11-18 16:43:48.626 paycomponentsvrDlg.cpp:1696 [6516] MERCHCODE :[32550440](8)2015-11-18 16:43:48.629 paycomponentsvrDlg.cpp:1696 [6516] ORDERNO :[110000050080000001321118164348](30)2015-11-18 16:43:48.631 paycomponentsvrDlg.cpp:1696 [6516] ORDERDATE :[20151118164348](14)2015-11-18 16:43:48.633 paycomponentsvrDlg.cpp:1696 [6516] PAYTYPE :[02001003](8)2015-11-18 16:43:48.634 paycomponentsvrDlg.cpp:1696 [6516] ISSCODE :[XXXX ](10)2015-11-18 16:43:48.635 paycomponentsvrDlg.cpp:1696 [6516] MTYPE :[156](3)2015-11-18 16:43:48.637 paycomponentsvrDlg.cpp:1696 [6516] PAYAMOUNT :[000000000100](12)2015-11-18 16:43:48.638 paycomponentsvrDlg.cpp:1696 [6516] PAYOBJ :[1000111100000077767 ](30)2015-11-18 16:43:48.639 paycomponentsvrDlg.cpp:1696 [6516] PAYACCOUNT :[1000111100000008067 ](30)2015-11-18 16:43:48.640 paycomponentsvrDlg.cpp:1696 [6516] POSMSG :[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaassssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhjjjjjjjjjjjjjj](300)
- 高效率、灵活打印结构体串(C语言版)
- FILE结构体(C语言版) (转)
- FILE结构体(C语言版)
- FILE结构体(C语言版)
- [转]FILE结构体(C语言版)
- 读数据结构(C语言版)
- 文件操作 FILE结构体(C语言版) (转)
- 串及其操作(C语言版)
- 俄罗斯方块(C语言版)
- 数据结构(C语言版)
- 数据结构(C语言版)
- Makefile(c语言版)
- 俄罗斯方块(C语言版)
- 万年历(C语言版)
- 队列(C语言版)
- 单链表(c语言版)
- 数据结构(C语言版)
- 快速排序(c语言版)
- [OpenCV] VS2010中OpenCV2.X配置Debug和Release同时正常使用
- List集合Null值判断新技能
- Git学习笔记
- JAVA 播放声音
- IOS 程序员开发最常用宏定义
- 高效率、灵活打印结构体串(C语言版)
- html5 在移动端禁止页面缩放和选中复制
- 为了梦想-程序媛也有春天
- AWS免费云主机之如何使用putty登录
- jsp spring mvc 上传时HTTP Status 405 - Request method 'GET' not supported是什么原因
- 消息队列使用,异步执行,加快速度
- ViewSwitcher和TextSwithcher打造不一样的视觉效果
- 利用Excel的vba脚本根据数据库表结构自动生成java的action,bean,dao,mode,service,xml,sql,jsp等
- Linux内存管理之mmap详解