tags:

views:

273

answers:

4

Hi,

my struct is some like this

typedef struct {
  type1 thing;
  type2 thing2;
  ...
  typeN thingN;
} my_struct 

how to enumerate struct childrens in a loop such as while, or for? thanks in advance.

+3  A: 

There is no safe way to enumerate a struct's members, unless the exact contents of the struct is known, and even in that case you have to be careful of things like struct alignment/padding.

Depending on your problem, it might be safer to have an array of your struct.

Brian R. Bondy
A: 

Since you plan to handle them in a loop, I assume the different types can at least be treated alike, or have similar sizes.

If this is the case, your choice will depend on the size of the elements. If they're all the same, you can retrieve a pointer to the structure, cast it to one of your types, and increment it until you 'used up' the whole structure.

PS: Indeed, not a very safe practice. This a situation handled much better with an OO approach, taking advantage of polymorphism. Otherwise, there's no guarantees about alignment as previously mentioned.

danielkza
A: 

There's no way to iterate through struct members in C language, regardless of whether the have the same size/type or different sizes/types.

AndreyT
+5  A: 

I'm not sure what you want to achieve, but you can use X-Macros and have the preprocessor doing the iteration over all the fields of a structure:

//--- first describe the structure, the fields, their types and how to print them
#define X_FIELDS \
    X(int, field1, "%d") \
    X(int, field2, "%d") \
    X(char, field3, "%c") \
    X(char *, field4, "%s")

//--- define the structure, the X macro will be expanded once per field
typedef struct {
#define X(type, name, format) type name;
    X_FIELDS
#undef X
} mystruct;

void iterate(mystruct *aStruct)
{
//--- "iterate" over all the fields of the structure
#define X(type, name, format) \
         printf("mystruct.%s is "format"\n", #name, aStruct->name);
X_FIELDS
#undef X
}

//--- demonstrate
int main(int ac, char**av)
{
    mystruct a = { 0, 1, 'a', "hello"};
    iterate(&a);
    return 0;
}

This will print :

mystruct.field1 is 0
mystruct.field2 is 1
mystruct.field3 is a
mystruct.field4 is hello

You can also add the name of the function to be invoked in the X_FIELDS...

philippe
thanks for you introducing me to X-Macro, great answer!
drigoSkalWalker