Last active
March 23, 2017 02:58
-
-
Save lixingcong/5ed663dbb0343da563df10570370c878 to your computer and use it in GitHub Desktop.
读取结构体C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdio.h" | |
#include "stdlib.h" | |
#include "string.h" | |
#define is_char_num(c) ((c>='0')&&(c<='9')) | |
/* | |
* brief: 从字符串取出数字 | |
* 注意str字符串结束符要有NULL,否则指针越界 | |
* param: str 字符串指针 | |
* offset 数字宽度 | |
* return: int 数字 | |
*/ | |
int getIntNumFromString(char *str, int *offset){ | |
int buf_i=0; | |
char buf[20],c_tmp; | |
*(offset)=0; | |
do{ | |
c_tmp=*(str+(*offset)); | |
buf[buf_i++]=c_tmp; | |
(*offset)++; | |
}while(is_char_num(c_tmp)); | |
(*offset)--; | |
buf_i--; | |
buf[buf_i]=0; // NULL | |
return atoi(buf); | |
} | |
/* | |
* brief: 打印出结构体的成员 | |
* 注意有的编译器默认启用4字节对齐。此时考虑对齐后的偏移量 | |
* param: fmt 格式控制串 | |
* 格式为 "偏移地址,输出格式,数据类型;" | |
* 例如 "400,%d,i;" 表示偏移400,输出格式是"%d",数据为int型 | |
* 数据类型前加上数字可以表示重复次数 | |
* 例如 "400,%d,6i;" 表示偏移400,输出格式是"%d",输出6个int型数据 | |
* 不同格式可以串联使用 | |
* 例如 "400,%d,6i;500,%s,s" | |
* data 输入结构体的指针 | |
* return: void | |
*/ | |
void print1(char *fmt, void *data){ | |
#define PRINT_FORMAT_FLOAT 'f' | |
#define PRINT_FORMAT_DOUBLE 'd' | |
#define PRINT_FORMAT_INT 'i' | |
#define PRINT_FORMAT_UINT 'I' | |
#define PRINT_FORMAT_CHAR 'c' | |
#define PRINT_FORMAT_UCHAR 'C' | |
#define PRINT_FORMAT_SHORT 'h' | |
#define PRINT_FORMAT_USHORT 'H' | |
#define PRINT_FORMAT_STRING 's' | |
// 控制串 | |
char fmt_printf[20]={0}; | |
// 临时buffer | |
int i,char_num_offset; | |
// 全局串的下标 | |
int index=0; | |
int offset_base,repeat,offset; | |
// for beautify output | |
printf("\r\n-------\r\n"); | |
while(index<strlen(fmt)){ | |
// 取出偏移 | |
offset_base=getIntNumFromString(fmt+index,&char_num_offset); | |
index+=char_num_offset; | |
if(*(fmt+index)!=','){ | |
return; | |
} | |
index++; // skip ',' | |
// 取出printf格式符 | |
i=0; | |
while(*(fmt+index)!=','){ | |
fmt_printf[i++]=*(fmt+(index++)); | |
} | |
fmt_printf[i]=0; // NULL | |
index++; // skip ',' | |
// 取出重复次数 | |
if(is_char_num(*(fmt+index))){ | |
repeat=getIntNumFromString(fmt+index,&char_num_offset); | |
index+=char_num_offset; | |
}else{ | |
repeat=1; | |
} | |
// 输出结果 | |
for(i=0;i<repeat;i++){ | |
// 取出数据类型 | |
switch(*(fmt+index)){ | |
case PRINT_FORMAT_FLOAT: | |
offset=offset_base+i*sizeof(float); | |
printf("offset=%d, data=",offset); | |
printf(fmt_printf,*(float *)(data+offset)); | |
break; | |
case PRINT_FORMAT_DOUBLE: | |
offset=offset_base+i*sizeof(double); | |
printf("offset=%d, data=",offset); | |
printf(fmt_printf,*(double *)(data+offset)); | |
break; | |
case PRINT_FORMAT_INT: | |
offset=offset_base+i*sizeof(int); | |
printf("offset=%d, data=",offset); | |
printf(fmt_printf,*(int *)(data+offset)); | |
break; | |
case PRINT_FORMAT_UINT: | |
offset=offset_base+i*sizeof(unsigned int); | |
printf("offset=%d, data=",offset); | |
printf(fmt_printf,*(unsigned int*)(data+offset)); | |
break; | |
case PRINT_FORMAT_STRING: | |
case PRINT_FORMAT_CHAR: | |
offset=offset_base+i*sizeof(char); | |
printf("offset=%d, data=",offset); | |
printf(fmt_printf,*(char *)(data+offset)); | |
break; | |
case PRINT_FORMAT_UCHAR: | |
offset=offset_base+i*sizeof(unsigned char); | |
printf("offset=%d, data=",offset); | |
printf(fmt_printf,*(unsigned char*)(data+offset)); | |
break; | |
case PRINT_FORMAT_SHORT: | |
offset=offset_base+i*sizeof(short); | |
printf("offset=%d, data=",offset); | |
printf(fmt_printf,*(short *)(data+offset)); | |
break; | |
case PRINT_FORMAT_USHORT: | |
offset=offset_base+i*sizeof(unsigned short); | |
printf("offset=%d, data=",offset); | |
printf(fmt_printf,*(unsigned short*)(data+offset)); | |
break; | |
default: | |
printf("data type error!"); | |
return; | |
break; | |
} | |
printf("\n"); | |
} | |
index++; // skip data type | |
if(*(fmt+index)!=';' || *(fmt+index)==0){ | |
return; | |
} | |
index++; // skip ';' | |
} | |
} | |
#undef is_char_num | |
typedef struct{ | |
int a; | |
float c; | |
unsigned char b,d; | |
}s1_t; | |
typedef struct{ | |
int a; | |
unsigned char b,d; | |
float c; | |
}s2_t; | |
int main(int argc, char **argv) { | |
s1_t s1; | |
s2_t s2; | |
s2.a=s1.a=100; | |
s2.b=s1.b='b'; | |
s2.c=s1.c=5.23; | |
s2.d=s1.d='d'; | |
// 说明按4字节对齐 | |
printf("s1:\n"); | |
print1("0,%d,i;4,%f,f;8,%c,2c",&s1); | |
printf("s2:\n"); | |
print1("0,%d,i;4,%c,2c;8,%f,f",&s2); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment