How to parse data from a buffer into an array of structs?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MimiMi
    New Member
    • Aug 2007
    • 42

    How to parse data from a buffer into an array of structs?

    Hello
    I'm still kinda new at C and I have this buffer filled with data that I want to to 'parse' into a an array of structs. How do I do this?
    The only thing I can think of is for-loops, kinda 'bytewise', but there must be a better way?

    It's something like this:

    Code:
    char buf[BUFSIZE];
    
    struct table_entry{
    int length;
    int offset;
    char *name;
    }
    
    struct table_entry *tablearray = NULL;
    I allocate memory for the tablearray, data is read into the buf and then, how do I 'fill' the structs? The data in the buffer is of course 'structdata', I mean of the kind 'length,offset, name,length,off set,name...."

    Hope someone knows what I mean and can help me, that would be so very kind of you!
    Cheers!
  • Ambrish Kinariwala
    New Member
    • Mar 2008
    • 6

    #2
    You can use memcpy function in your code.

    [code=c]
    Code: ( text )
    char buf[BUFSIZE];
    struct table_entry{
    int length;
    int offset;
    char *name;
    }
    struct table_entry *tablearray = NULL;

    [/code]

    I am assuming that the buffer has valid data that is aligned properly with the struct table_entry. As you mentioned you will need a for loop to copy the number the entries which you should maintain a count of. I am supposing the number of entries to be variable n.

    [code=c]
    int i = 0;
    /* Allocate the memory for tablearray */
    tablearray = malloc(...);
    for(i=0;i < n;i++) {
    memcpy(tablearr ay, buf, sizeof(table_en try));
    }
    [/code]

    I hope this helps.
    Ambrish Kinariwala

    Comment

    • mac11
      Contributor
      • Apr 2007
      • 256

      #3
      Originally posted by MimiMi
      Hello
      I'm still kinda new at C and I have this buffer filled with data that I want to to 'parse' into a an array of structs. How do I do this?
      The only thing I can think of is for-loops, kinda 'bytewise', but there must be a better way?

      It's something like this:

      Code:
      char buf[BUFSIZE];
      
      struct table_entry{
      int length;
      int offset;
      char *name;
      }
      
      struct table_entry *tablearray = NULL;
      I allocate memory for the tablearray, data is read into the buf and then, how do I 'fill' the structs? The data in the buffer is of course 'structdata', I mean of the kind 'length,offset, name,length,off set,name...."

      Hope someone knows what I mean and can help me, that would be so very kind of you!
      Cheers!
      I want to help but I don't want to write a bunch of stuff that you might already know. Help me understand how far along in the process you are.

      Do you have code to open the input file and read it into your parse buffer?
      Have you figured out the high level algorithm for parsing a struct worth of data?
      Do you have any parse code?

      --
      Ambrish's code is likely not to work because sizeof( struct table_entry) only gives you enough memory to hold 'name' address, not space to actually hold the name (which may be 1024 bytes for all anybody knows - you have to read 'length' to know that).
      Last edited by mac11; Mar 31 '08, 04:45 PM. Reason: ambrish types faster than me

      Comment

      • MimiMi
        New Member
        • Aug 2007
        • 42

        #4
        Originally posted by mac11
        Do you have code to open the input file and read it into your parse buffer?
        Have you figured out the high level algorithm for parsing a struct worth of data?
        Do you have any parse code?
        Thank you both for taking the time trying to help me!

        I have the code to open the input file and read it into my parse buffer yes, so I guess my problem is figuring out the high level parsing a struct worth of data algorithm!

        No, I don't have any parse code yet (if I understand that last question correctly), that's kinda the problem..

        Thanks again!

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Forget the array if structs. You have not mentioned your file format. It's not so much that you parse into an array of structs but more imprtant that you know the data you are reading.

          If you can read the data an populate one struct variable, then an array is simple.

          So, what does your data look like?

          Comment

          • MimiMi
            New Member
            • Aug 2007
            • 42

            #6
            Originally posted by weaknessforcats
            Forget the array if structs. You have not mentioned your file format. It's not so much that you parse into an array of structs but more imprtant that you know the data you are reading.

            If you can read the data an populate one struct variable, then an array is simple.

            So, what does your data look like?
            That's the thing, that's my problem: populating that one struct variable!

            Maybe it's just that my problem is too simple, that's why you all have a hard time understanding what I mean? (And of course, I'm not too great at describing my problem clearly either I guess..)

            Let's put it this way: If I have a buffer filled with bytes, and I want to populate a struct out of it, how do I do that?

            It's something like this
            Code:
            struct table_entry{
            int length;
            int offset;
            char *name;
            }
            char buf[BUFSIZE]; 
            
            struct table_entry entry;
            
            entry.length = //The first 4 bytes of buf
            entry.offset = //The next 4 bytes of buf
            entry.name = //The next 16 bytes of buf
            My problem is the comments, what should the code look like there?
            Hope I'm being a little bit clearer, and sorry for being such a newbie..

            Comment

            • MimiMi
              New Member
              • Aug 2007
              • 42

              #7
              Originally posted by MimiMi
              Code:
              struct table_entry{
              int length;
              int offset;
              char *name;
              }
              char buf[BUFSIZE]; 
              
              struct table_entry entry;
              
              entry.length = //The first 4 bytes of buf
              entry.offset = //The next 4 bytes of buf
              entry.name = //The next 16 bytes of buf
              My problem is the comments, what should the code look like there?
              Maybe you can do it like this?
              Code:
              memcpy(entry.length,buf,4);
              memcpy(entry.offset,buf+4,4);
              memcpy(entry.name,buf+8,16);
              Cheers!

              Comment

              • mmk
                New Member
                • Oct 2006
                • 19

                #8
                Originally posted by MimiMi
                Maybe you can do it like this?
                Code:
                memcpy(entry.length,buf,4);
                memcpy(entry.offset,buf+4,4);
                memcpy(entry.name,buf+8,16);
                Cheers!
                Hi Mimimi while trying out your query, i coded in this way but its not working out. Can you please share your code snippet. Anybody can help out me regarding this.

                Code:
                #include <stdio.h>
                
                #define BUFSIZE 100
                
                char buf[BUFSIZE][BUFSIZE]={ 1,3,"Trying",2,4,"out",4,5,"something"};
                
                struct table_entry{
                int length;
                int offset;
                char *name;
                }
                
                struct table_entry *tablearray = NULL;
                memset(tablearray,0,BUFSIZE);
                tablearray = (table_entry*)malloc(sizeof(BUFSIZE));
                
                int main()
                {
                    int i;
                    for(i=0;i<BUFSIZE;i++)
                    {
                        memcpy(tablearray.length,buf,4);
                        memcpy(tablearray.offset,buf+4,4);
                        memcpy(tablearray.offset,buf+16,16);
                    }
                    return 0;
                }
                Thanks in advance,
                mmk

                Comment

                • MimiMi
                  New Member
                  • Aug 2007
                  • 42

                  #9
                  Thank you all for taking the time to try and help me with this!
                  The problem is now solved!

                  memcpy was no good idea!
                  And also, the struct member 'name' worked much better looking like this
                  Code:
                  struct table_entry {
                    int length;
                    int offset;
                    char name[NAMESIZE];
                  };
                  instead of 'char *name'. And I didn't need an 'intermediate' buffer but could get the struct-data 'straight away'. Kinda like this (pseudocode):
                  Code:
                  struct table_entry *tablearray;
                  int TABLESIZE = 64;
                  int i,offset = 0;
                  struct table_entry entry;
                  tablearray = mem_alloc(sizeof (struct table_entry) * TABLESIZE);
                  read_from_file(file,(unsigned char*)tablearray,offset,TABLESIZE);
                  Then I could access the data like this
                  Code:
                  for(i=0; i<TABLESIZE;i++)
                  {
                  entry.len = tablearray[i].len;
                  entry.offset = tablearray[i].offset;
                  strncpy(entry.name,tablearray[i].name,NAMESIZE);
                  }
                  Again, thank you all, and take care!
                  Cheers!

                  Comment

                  • weaknessforcats
                    Recognized Expert Expert
                    • Mar 2007
                    • 9214

                    #10
                    Originally posted by MimiMi
                    And also, the struct member 'name' worked much better looking like this

                    Code: ( text )
                    struct table_entry {
                    int length;
                    int offset;
                    char name[NAMESIZE];
                    };

                    instead of 'char *name'. And I didn't need an 'intermediate' buffer but could get the struct-data 'straight away'.
                    Yes, but you also built a limit into your code: NAMESIZE. That means if NAMESIZE is 80, a name like MimiMi will take 80 bytes instead of 6. Now your program is larger and slower.

                    Stick with the pointer.

                    If you have a buffer with a C-string in it, all you need to do si allocate memory and then copy the string to your struct variable:
                    [code=c]
                    struct data
                    {
                    char* name;
                    };

                    char buffer[SOMESIZE];
                    struct data var;
                    var.data = (char*)malloc(( strlen(buffer) + 1) * sizeof(char));
                    strcpy(var.data , buffer);
                    [/code]

                    var now has a copy of the data.

                    I aksed about your file format since some of your struct members were ints and you cannot have ints in a text file. Text file have only chars. However, I never saw yout file layout or your read code so I really can't see what you are doing.

                    Originally posted by mmk
                    char buf[BUFSIZE][BUFSIZE]={ 1,3,"Trying",2, 4,"out",4,5,"so mething"};
                    An array has to have elements that are the same type. This one has int and char*. I expect the compiler will gag on it.

                    Again, this comes down to data format. You cannot read data unles you know the format.

                    Comment

                    Working...