找回密码
 欢迎注册
查看: 32933|回复: 7

[求助] C/C++中如何遍历结构体的元素?

[复制链接]
发表于 2013-5-11 10:01:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
我现在有一个需求: 已知某人给我提供了 一个动态库,和对应的头文件。头文件里面描述了结构体的各种元素,大概有50多个,元素全是char数组,大小不一。 我现在需要遍历这些元素,把它们join成一个字符串,可有什么便捷的好方法,我该不会一个一个的用操作符 ->取出来吧?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-12 19:53:07 | 显示全部楼层
不知道你说的是什么样的结构体,如果不是指针类型而是已明确了成员的char var[N]; 这种情况下,结构体大小是确定的sizeof ,数据是一片连续内存块,那么就不需要知道各个成员是什么名字。 接下来就是去掉这内存块里面的零值。 最后printf.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2013-5-12 23:37:27 | 显示全部楼层
2# G-Spider 有50多个成员,每一个成员都是char var[N], 但每一个成员的N是不一样的,没有规律。 去掉内存块的零值是啥意思,求解释。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-13 21:22:05 | 显示全部楼层
3# wayne 偷懒的局限性在代码的注释中
  1. #include <stdio.h>
  2. #include <string.h>
  3. typedef struct
  4. {
  5. char d0[12];
  6. char d1[6];
  7. char d2[5];
  8. }tD,*pD;
  9. void removezero(char *dst,char *src,int len)
  10. {
  11. char *p=src;
  12. int i;
  13. for(i=0;i<len;i+=strlen(p)+1)
  14. {
  15. p=src+i;
  16. strcat(dst,p);
  17. }
  18. }
  19. void main()
  20. {
  21. pD src=NULL,dst=NULL;
  22. src=(pD)malloc(sizeof(tD));
  23. dst=(pD)malloc(sizeof(tD));
  24. if(NULL==src|| NULL==dst)
  25. return;
  26. memset(dst,0,sizeof(tD));
  27. memset(src,0,sizeof(tD)); /*块需初始化为0*/
  28. strcpy(src->d0,"good");
  29. strcpy(src->d1,"luck");
  30. strcpy(src->d2,"man");
  31. /*-------------------join---------------------*/
  32. removezero((char *)dst,(char *)src,sizeof(tD));
  33. printf("%s\n",dst);
  34. system("pause");
  35. }
复制代码

评分

参与人数 1威望 +6 经验 +6 鲜花 +6 收起 理由
wayne + 6 + 6 + 6 thanks

查看全部评分

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2013-5-14 11:05:34 | 显示全部楼层
4# G-Spider 不错,有点tricky,我知道怎么做了。 我的实际需求其实是把结构体的都是char []的成员用逗号 join 成一个字符串。 =========== BTW,貌似高手都不太喜欢用calloc呢,
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. typedef struct {
  5. char d0[12];
  6. char d1[6];
  7. char d2[5];
  8. } tD,*pD;
  9. void removezero(char *dst,char *src,int len)
  10. {
  11. char *p=src;
  12. int i;
  13. for(i=0; i<len; i+=strlen(p)+1) {
  14. p=src+i;
  15. strcat(dst,p);
  16. }
  17. }
  18. int main()
  19. {
  20. pD src=NULL,dst=NULL;
  21. src=(pD)calloc(1,sizeof(tD));
  22. dst=(pD)calloc(1,sizeof(tD));
  23. if(NULL==src|| NULL==dst)
  24. return 1;
  25. // memset(dst,0,sizeof(tD));
  26. // memset(src,0,sizeof(tD)); /*彘濮邃负0*/
  27. strcpy(src->d0,"good");
  28. strcpy(src->d1,"luck");
  29. strcpy(src->d2,"man");
  30. /*-------------------join---------------------*/
  31. removezero((char *)dst,(char *)src,sizeof(tD));
  32. printf("%s\n",(char *)dst);
  33. // system("pause");
  34. return 0;
  35. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-14 12:49:19 | 显示全部楼层
修改下removezero逗号分隔 for(...) { p=src+i; if(*p) { strcat(dst,p); dst[strlen(dst)]=','; } } dst[strlen(dst)-1]=0;
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-14 20:34:42 | 显示全部楼层
4# G-Spider 不错,有点tricky,我知道怎么做了。 我的实际需求其实是把结构体的都是char []的成员用逗号 join 成一个字符串。 =========== BTW,貌似高手都不太喜欢用calloc呢,#include #include #inc ... wayne 发表于 2013-5-14 11:05
以前只知道 malloc/realloc/free,还真没注意到calloc; 刚刚查了下MSDN,alloc 与realloc一样有一个额外动作:分配内存中的一个数组的元素初始化为 0。 alloc 似乎还有一个特殊功能:可得到确保为存储指定对象的内存对齐。 但是,数据对齐现在有了更好的函数:_aligned_malloc / _aligned_offset_malloc / _aligned_free 再加上 memset 函数,即可达到相同目的,且更自由。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-14 22:19:30 | 显示全部楼层
5#,哈,主要是用习惯了吧, malloc的好处是,是否需要初始化memset倒可以放到需要的地方。 郭说的这个分配一个数据对齐的内存,只前尝试大数库的时候倒有体会,也思考了很久,特别是为了有个16字节对齐的内存好SSE的相关处理。 7# 提到的_aligned_malloc /_aligned_free 第一次听到,由于不是标准库里的函数,于是百度了一下想知道其原理,发现与我之前想的一致: 就是多申请一些空间用于保存申请的内存的原地址,以便用于释放。 而保存原地址的位置在对齐边界后p的前一个sizeof(void *)的地方即&p[-1],里面的值p[-1]为原malloc返回的地址,p是对齐后的地址。
  1. #include <stdio.h>
  2. void* _mm_malloc (size_t size, size_t align)
  3. {
  4. void * malloc_ptr;
  5. void * aligned_ptr;
  6. /* Error if align is not a power of two. */
  7. if (align & (align - 1))
  8. {
  9. return ((void*) 0);
  10. }
  11. if (size == 0)
  12. return ((void *) 0);
  13. /* Assume malloc'd pointer is aligned at least to sizeof (void*).
  14. If necessary, add another sizeof (void*) to store the value
  15. returned by malloc. Effectively this enforces a minimum alignment
  16. of sizeof double. */
  17. if (align < 2 * sizeof (void *))
  18. align = 2 * sizeof (void *);
  19. malloc_ptr =(void *)malloc(size + align);
  20. if (!malloc_ptr)
  21. return ((void *) 0);
  22. /* Align We have at least sizeof (void *) space below malloc'd ptr. */
  23. aligned_ptr = (void *) (((size_t) malloc_ptr + align)
  24. & ~((size_t) (align) - 1));
  25. /* Store the original pointer just before p. */
  26. ((void **) aligned_ptr) [-1] = malloc_ptr;
  27. return aligned_ptr;
  28. }
  29. void _mm_free (void * aligned_ptr)
  30. {
  31. if (aligned_ptr)
  32. free (((void **) aligned_ptr) [-1]);
  33. }
  34. void main()
  35. {
  36. char *data;
  37. /* 没用过[-1]的数组定位方式,测试一下*/
  38. char d[4]={'a','b','c','d'};
  39. char *p=&d[2];
  40. printf("%c\n",p[-1]);
  41. /**************************************/
  42. data=(char *)_mm_malloc(12,64);
  43. printf("%p %08X\n",data,((unsigned int *)data)[-1]);
  44. _mm_free(data);
  45. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-9-24 09:29 , Processed in 0.024617 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表