how to iterate through all members in a struct

Discussion in 'C Programming' started by jaso, Jun 10, 2006.

  1. jaso

    jaso Guest

    Hi,

    If have a structure of a database record like this:
    struct record {
    char id[ID_LENGTH];
    char title[TITLE_LENGTH];
    ...
    };
    Is there some way to find out how many member variables there is
    in the struct and then iterate through them?
    I want to have a function that takes the struct as argument and
    then prompts the user for input for all the members. And instead
    of coding the input for every member variable, I want the function
    to automatically update each member. That will make it easier to
    update the struct with more members.
    The function also needs to know the length of every string in the
    struct, so maybe I should add a length variable to each string
    in the struct.

    Is that feasible? Or can you recommend an other way?
     
    jaso, Jun 10, 2006
    #1
    1. Advertising

  2. jaso

    Jolting Guest

    In C you can't just add something to a struct without recompiling.
    One thing you can do is create a stack.
    struct record_entry{
    char field_name[20];
    char field_data[MAXSIZE];
    struct record_entry *next;
    }
    then each time you want to add something.
    you put the next thing on the end of the stack.

    record->record_entry->record_entry->record_entry->NULL
    The trick to interating through something like this is to set the last
    entry as NULL.
    It will only be NULL if it gets to the end.

    int main(){
    struct record_entry record, *new;
    new = (struct record_entry*)malloc(sizeof(record));
    record.next = new;
    new->next = NULL;
    }


    jaso wrote:
    > Hi,
    >
    > If have a structure of a database record like this:
    > struct record {
    > char id[ID_LENGTH];
    > char title[TITLE_LENGTH];
    > ...
    > };
    > Is there some way to find out how many member variables there is
    > in the struct and then iterate through them?
    > I want to have a function that takes the struct as argument and
    > then prompts the user for input for all the members. And instead
    > of coding the input for every member variable, I want the function
    > to automatically update each member. That will make it easier to
    > update the struct with more members.
    > The function also needs to know the length of every string in the
    > struct, so maybe I should add a length variable to each string
    > in the struct.
    >
    > Is that feasible? Or can you recommend an other way?
     
    Jolting, Jun 10, 2006
    #2
    1. Advertising

  3. >If have a structure of a database record like this:
    >struct record {
    > char id[ID_LENGTH];
    > char title[TITLE_LENGTH];
    > ...
    >};
    >Is there some way to find out how many member variables there is
    >in the struct and then iterate through them?


    No. And iterating through variables of unknown type is of questionable
    usefulness.

    >I want to have a function that takes the struct as argument and
    >then prompts the user for input for all the members. And instead
    >of coding the input for every member variable, I want the function
    >to automatically update each member.


    With very rare exceptions (like deallocation of auto variables), C
    doesn't "automatically" anything. You have to write code for that.

    >That will make it easier to
    >update the struct with more members.
    >The function also needs to know the length of every string in the
    >struct, so maybe I should add a length variable to each string
    >in the struct.


    >Is that feasible? Or can you recommend an other way?


    It *is* possible to create a description of the structure,
    giving the prompt, size limit, offset (using the offsetof() macro),
    allowed character set, etc. of each field, and have your function
    use that. Of course, you have to remember to update it.

    Gordon L. Burditt
     
    Gordon Burditt, Jun 10, 2006
    #3
  4. jaso

    jaso Guest

    jaso wrote:
    > Hi,
    >
    > If have a structure of a database record like this:
    > struct record {
    > char id[ID_LENGTH];
    > char title[TITLE_LENGTH];
    > ...
    > };
    > Is there some way to find out how many member variables there is
    > in the struct and then iterate through them?
    > I want to have a function that takes the struct as argument and
    > then prompts the user for input for all the members. And instead
    > of coding the input for every member variable, I want the function
    > to automatically update each member. That will make it easier to
    > update the struct with more members.
    > The function also needs to know the length of every string in the
    > struct, so maybe I should add a length variable to each string
    > in the struct.
    >
    > Is that feasible? Or can you recommend an other way?


    This is one way I come up with, what do you think about it?

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define NOT_NULL 1
    #define NUMERIC 2
    #define MULTI_LINE 4

    struct field_desc {
    char *name;
    int length;
    int type;
    };

    struct field_desc movies_desc[] = {
    { "id", 1, NOT_NULL | NUMERIC },
    { "test", 34, 0 },
    { "title", 50, NOT_NULL },
    { "genre", 15, NOT_NULL },
    { "length", 3, NOT_NULL | NUMERIC },
    { "description", 65535, MULTI_LINE },
    { "owner", 10, NOT_NULL } };

    #define MOVIES_LENGTH (sizeof(movies_desc)/sizeof(movies_desc[0]))

    /* fills record with input data from user */
    int fill_record(char *entries[], struct field_desc desc[], int length)
    {
    int i;
    for (i = 0; i < length; i++) {
    if (fill_string(desc.name, &entries,
    desc.length, desc.type) != 0)
    return -1;
    }
    return 0;
    }

    int fill_string(char *prompt, char **str, int length, int type)
    {
    size_t len;
    *str = malloc(length + 1);
    if (*str == NULL)
    return -1;

    printf("%s: ", prompt);
    fflush(stdout);
    fgets(*str, length + 1, stdin);

    if (!(type & MULTI_LINE)) {
    len = strlen(*str);

    if ((*str)[len - 1] == '\n')
    (*str)[len - 1] = '\0';
    }

    return 0;
    }

    int main(void)
    {
    char *movies_record[MOVIES_LENGTH];

    /* connect to database */
    /* snipped */

    fill_record(movies_record, movies_desc, MOVIES_LENGTH);

    /* database stuff */

    return EXIT_SUCCESS;
    }

    I know its not bug free, but thats not the point now.
    This way I can just add one element to the field_desc array
    and nothing more needs to be modified. But at the call
    to fill_record I need to pass the array containing the
    fields, the description and the length.
    Maybe it would be cleaner if this data could be
    stored in one struct.

    struct movies_record {
    char *entries[MOVIES_LENGTH];
    struct field_desc *desc;
    int length;
    };

    But here the desc and length variables can point to anything,
    but I want it to just point to movies_desc and length set to
    MOVIES_LENGTH;
    i.e I would want something like this
    struct movies_record {
    char *entries[MOVIES_LENGTH];
    struct field_desc *desc = movies_desc;
    int length = MOVIES_LENGTH;
    };
    which is illegal..
    So I really don't know how to do it. Any opinions?
     
    jaso, Jun 10, 2006
    #4
  5. jaso

    Malcolm Guest

    "jaso" <> wrote in message
    >
    > If have a structure of a database record like this:
    > struct record {
    > char id[ID_LENGTH];
    > char title[TITLE_LENGTH];
    > ...
    > };
    > Is there some way to find out how many member variables there is
    > in the struct and then iterate through them?
    > I want to have a function that takes the struct as argument and
    > then prompts the user for input for all the members. And instead
    > of coding the input for every member variable, I want the function
    > to automatically update each member. That will make it easier to
    > update the struct with more members.
    > The function also needs to know the length of every string in the
    > struct, so maybe I should add a length variable to each string
    > in the struct.
    >
    > Is that feasible? Or can you recommend an other way?
    >

    No.
    If we've got a database of employees, we can hardcode something like

    struct employee
    {
    char name[64];
    int serialnumber;
    double salary;
    };

    Unfortunately in a real application we probably want the user to be able to
    add and delete fields, without recompiling the program.

    There is no easy way of achieving this. If you look at SQL you will see that
    there are a limited number of atomic data types. You can write an SQL-type
    server by defining a record signature string. Then you query the fields by
    name and extract the values.

    So we've got something like

    "id: char[32]
    title: varchar
    ... other members
    "
    In our record format descriptor

    Then we have

    struct record
    {
    int Nfields;
    char **fieldname;
    int *fieldtype;
    int *fieldlength;
    void **data;
    };

    for the general record, and we can build the structure from the record
    descriptor
    then we have an

    int extractcharfield(struct record *rec, char *fieldname, char *out)

    to access the data.

    It is quite complicated to build from the ground up.

    --
    Buy my book 12 Common Atheist Arguments (refuted)
    $1.25 download or $7.20 paper, available www.lulu.com/bgy1mm
     
    Malcolm, Jun 11, 2006
    #5
  6. [Gordon's been snipping attribs again, so I can't tell to whom he is
    replying. Oh well.]

    Gordon Burditt said:

    >>If have a structure of a database record like this:
    >>struct record {
    >>char id[ID_LENGTH];
    >>char title[TITLE_LENGTH];
    >>...
    >>};
    >>Is there some way to find out how many member variables there is
    >>in the struct and then iterate through them?

    >
    > No.


    Yes, if you have access to the source for the struct.

    > And iterating through variables of unknown type is of questionable
    > usefulness.


    I can think of a few times when it would have been handy to be able to
    iterate programmatically through the members of a struct, especially if one
    had access to their names and types as well.

    <snip>

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Jun 11, 2006
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gogo
    Replies:
    1
    Views:
    2,106
    Sudsy
    Sep 4, 2003
  2. runescience
    Replies:
    0
    Views:
    1,462
    runescience
    Feb 9, 2006
  3. Rob Meade

    Iterate through all panels on webform?

    Rob Meade, Jan 16, 2007, in forum: ASP .Net
    Replies:
    0
    Views:
    323
    Rob Meade
    Jan 16, 2007
  4. John
    Replies:
    4
    Views:
    922
    RedGrittyBrick
    Apr 1, 2008
  5. John Reye
    Replies:
    28
    Views:
    1,377
    Tim Rentsch
    May 8, 2012
Loading...

Share This Page