referring to struct members by number.

E

edson

Greetings
For certain operations I would like to have easy access to struct
members. Here is an example.

struct mystruct {
char member1[3];
char member1[50];
char member1[12];
};

/* print the strings in the struct */

for(i=0; i<3; i++){
switch(i):
case 0:
printf(" %s\r\n", mystruct.member1 );
break;
case 0:
printf(" %s\r\n", mystruct.member2 );
break;
case 0:
printf(" %s\r\n", mystruct.member3 );
break;
}

This is very cumbersom, sepecially for large structs. Is there some way
I could avoid having to name each member?
something like the following pseudocode;

for(i=0; i<3; i++){
print member i
}

I would appreciate advice on this.
Regards.
 
N

Nick Keighley

edson said:
Greetings
For certain operations I would like to have easy access to struct
members. Here is an example.

struct mystruct {
char member1[3];
char member1[50];
char member1[12];
};

/* print the strings in the struct */

for(i=0; i<3; i++){
switch(i):
case 0:
printf(" %s\r\n", mystruct.member1 );
break;
case 0:
printf(" %s\r\n", mystruct.member2 );
break;
case 0:
printf(" %s\r\n", mystruct.member3 );
break;
}

This is very cumbersom, sepecially for large structs. Is there some way
I could avoid having to name each member?
something like the following pseudocode;

for(i=0; i<3; i++){
print member i
}

I would appreciate advice on this.

an array of ptr to char?

char* jagged_array [3];

jagged_array[0] = malloc(3);
if (!jagged_array[0])
abort();

jagged_array[1] = malloc(50);
if (!jagged_array[1])
abort() ;

jagged_array[2] = malloc(12);
if (!jagged_array[2])
abort();

obviously this can be turned into a function

printing:-
for (i = 0; i < 3; i++)
printf ("%s" jagged_array);

code not compiled
 
M

Marc Boyer

Nick Keighley said:
Greetings
For certain operations I would like to have easy access to struct
members. Here is an example.

struct mystruct {
char member1[3];
char member1[50];
char member1[12];
};

/* print the strings in the struct */

for(i=0; i<3; i++){
switch(i):
case 0:
printf(" %s\r\n", mystruct.member1 );
break;
case 0:
printf(" %s\r\n", mystruct.member2 );
break;
case 0:
printf(" %s\r\n", mystruct.member3 );
break;
}

This is very cumbersom, sepecially for large structs. Is there some way
I could avoid having to name each member?
something like the following pseudocode;

for(i=0; i<3; i++){
print member i
}
an array of ptr to char?

3 dynamic allocations, 3 failure tests and 3 malloc overhead :-(
I would really prefer
struct mystruct {
char member1[3];
char member1[50];
char member1[12];
char* memtab[3];
};

void init_mystruct( struct mystruct* s){
s->memtab[0]= &(s->member1);
s->memtab[1]= &(s->member2);
s->memtab[2]= &(s->member3);
}

Marc Boyer
 
E

edson

The solution I am using is to (hand) write an array of pointers. This
has the disadvantage that it must be hand edited if the struct is changed.

Is there a risk that another compiler might put the members in different
locations with different offsets from the start of the struct? I am
using GCC and I find that the members are perfectly contiguous with no
gaps between them.


struct mystruct {
char member1[3];
char member2[50];
char member3[12];
};

s_l_fieldpos[] = {0, 3, 50};


/* print the strings in the struct */

for(i=0; i<3; i++){
printf(" %s\r\n", mystruct.member1[s_l_fieldpos]);
}
 
M

Marc Boyer

Le 13-12-2006 said:
The solution I am using is to (hand) write an array of pointers. This
has the disadvantage that it must be hand edited if the struct is changed.

Yes, like the print_myfunction function. There is no gain.
Is there a risk that another compiler might put the members in different
locations with different offsets from the start of the struct?

Yes. And even gcc could with some optimisation options or
in another version. This is why it exists the 'offsetof' facility.
I am
using GCC and I find that the members are perfectly contiguous with no
gaps between them.

struct mystruct {
char member1[3];
char member2[50];
char member3[12];
};

s_l_fieldpos[] = {0, 3, 50};
s_l_fieldpos[] = { offsetof(struct mystruct, member1),
offsetof(struct mystruct, member2),
offsetof(struct mystruct, member3) };
/* print the strings in the struct */

for(i=0; i<3; i++){
printf(" %s\r\n", mystruct.member1[s_l_fieldpos]);

printf(" %s\r\n", ((char*)mystruct) + s_l_fieldpos);

But, is this really simpler than
void print_myfunction(iconst struct mystruct * s){
printf(" %s\r\n", s->member1);
printf(" %s\r\n", s->member2);
printf(" %s\r\n", s->member3);
}

Marc Boyer
 
E

edson

Marc said:
Le 13-12-2006 said:
The solution I am using is to (hand) write an array of pointers. This
has the disadvantage that it must be hand edited if the struct is changed.


Yes, like the print_myfunction function. There is no gain.

Is there a risk that another compiler might put the members in different
locations with different offsets from the start of the struct?


Yes. And even gcc could with some optimisation options or
in another version. This is why it exists the 'offsetof' facility.

I am
using GCC and I find that the members are perfectly contiguous with no
gaps between them.

struct mystruct {
char member1[3];
char member2[50];
char member3[12];
};

s_l_fieldpos[] = {0, 3, 50};

s_l_fieldpos[] = { offsetof(struct mystruct, member1),
offsetof(struct mystruct, member2),
offsetof(struct mystruct, member3) };
/* print the strings in the struct */

for(i=0; i<3; i++){
printf(" %s\r\n", mystruct.member1[s_l_fieldpos]);


printf(" %s\r\n", ((char*)mystruct) + s_l_fieldpos);


But, is this really simpler than
void print_myfunction(iconst struct mystruct * s){
printf(" %s\r\n", s->member1);
printf(" %s\r\n", s->member2);
printf(" %s\r\n", s->member3);
}


It is more compact than print_myfunction, especially for a struct with
large number of members - the loop remains the same size with the
s_l_fieldpos[] array becoming just a little longer. It also has the
advantage that const int s_l_fieldpos[] = {0, 3, 50}; is stored in rom
and uses less of the precious ram. (It is a uC program.) s_l_fieldpos[]
= { offsetof(struc... puts the offsets in ram. It is good to discover
the offsetof() function. I didn't know about that.
 
M

Marc Boyer

Le 13-12-2006 said:
Marc said:
Le 13-12-2006, edson <[email protected]> a écrit :
But, is this really simpler than
void print_myfunction(iconst struct mystruct * s){
printf(" %s\r\n", s->member1);
printf(" %s\r\n", s->member2);
printf(" %s\r\n", s->member3);
}

It is more compact than print_myfunction, especially for a struct with
large number of members - the loop remains the same size with the
s_l_fieldpos[] array becoming just a little longer. It also has the
advantage that const int s_l_fieldpos[] = {0, 3, 50}; is stored in rom
and uses less of the precious ram.

OK, but you did not explain this constraint in your first post, did
you ?
(It is a uC program.) s_l_fieldpos[]
= { offsetof(struc... puts the offsets in ram. It is good to discover
the offsetof() function. I didn't know about that.

It is not of everyday use, but sometimes, it helps.

Marc Boyer
 
T

tedu

edson said:
Greetings
For certain operations I would like to have easy access to struct
members. Here is an example.

struct mystruct {
char member1[3];
char member1[50];
char member1[12];
};

/* print the strings in the struct */

for(i=0; i<3; i++){
switch(i):
case 0:
printf(" %s\r\n", mystruct.member1 );
break;
case 0:
printf(" %s\r\n", mystruct.member2 );
break;
case 0:
printf(" %s\r\n", mystruct.member3 );
break;
}

This is very cumbersom, sepecially for large structs. Is there some way
I could avoid having to name each member?
something like the following pseudocode;

for(i=0; i<3; i++){
print member i
}


using the boost headers, you can do this in the preprocessor provided
you number all your field names.

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <stdio.h>

struct mystruct {
char m1[3];
char m2[3];
char m3[3];
};
#define PRINTONE(z, n, stname) printf("%s\n", stname. BOOST_PP_CAT(m,
n) );
#define PRINT(stname) \
do { BOOST_PP_REPEAT_FROM_TO(1, 4, PRINTONE, stname) } while (0)
int main() {
struct mystruct st;
PRINT(st);
}
 
K

Keith Thompson

tedu said:
edson wrote: [snip]
This is very cumbersom, sepecially for large structs. Is there some way
I could avoid having to name each member?
something like the following pseudocode;

for(i=0; i<3; i++){
print member i
}


using the boost headers, you can do this in the preprocessor provided
you number all your field names.

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
[snip]

"boost" is not part of standard C. As far as I know, it's not C at
all; I think it's C++.

It *might* be a possible solution for the OP, but if so he'll need to
ask about it in another newsgroup, probably comp.lang.c++ (if boost is
topical there).
 
T

tedu

Keith said:
tedu said:
edson wrote: [snip]
This is very cumbersom, sepecially for large structs. Is there some way
I could avoid having to name each member?
something like the following pseudocode;

for(i=0; i<3; i++){
print member i
}


using the boost headers, you can do this in the preprocessor provided
you number all your field names.

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
[snip]

"boost" is not part of standard C. As far as I know, it's not C at
all; I think it's C++.

It *might* be a possible solution for the OP, but if so he'll need to
ask about it in another newsgroup, probably comp.lang.c++ (if boost is
topical there).

the boost preprocessor macros are implemented only in preprocessor. i
know boost itself isn't topical, but it saved me from having to
copy/paste the assorted macros into the posted code (which does compile
with a C compiler) to demonstrate a working example.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,216
Latest member
topweb3twitterchannels

Latest Threads

Top