468,457 Members | 1,598 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,457 developers. It's quick & easy.

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

42
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:

Expand|Select|Wrap|Line Numbers
  1. char buf[BUFSIZE];
  2.  
  3. struct table_entry{
  4. int length;
  5. int offset;
  6. char *name;
  7. }
  8.  
  9. struct table_entry *tablearray = NULL;
  10.  
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,offset,name...."

Hope someone knows what I mean and can help me, that would be so very kind of you!
Cheers!
Mar 31 '08 #1
9 8673
You can use memcpy function in your code.

Expand|Select|Wrap|Line Numbers
  1. Code: ( text )
  2.       char buf[BUFSIZE];
  3.       struct table_entry{
  4.        int length;
  5.        int offset;
  6.        char *name;
  7.        }
  8.     struct table_entry *tablearray = NULL;
  9.  
  10.  
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.

Expand|Select|Wrap|Line Numbers
  1. int i = 0;
  2. /* Allocate the memory for tablearray */
  3. tablearray = malloc(...);
  4. for(i=0;i < n;i++) {
  5. memcpy(tablearray, buf, sizeof(table_entry));
  6. }
  7.  
I hope this helps.
Ambrish Kinariwala
Mar 31 '08 #2
mac11
256 100+
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:

Expand|Select|Wrap|Line Numbers
  1. char buf[BUFSIZE];
  2.  
  3. struct table_entry{
  4. int length;
  5. int offset;
  6. char *name;
  7. }
  8.  
  9. struct table_entry *tablearray = NULL;
  10.  
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,offset,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).
Mar 31 '08 #3
MimiMi
42
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!
Mar 31 '08 #4
weaknessforcats
9,207 Expert Mod 8TB
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?
Mar 31 '08 #5
MimiMi
42
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
Expand|Select|Wrap|Line Numbers
  1. struct table_entry{
  2. int length;
  3. int offset;
  4. char *name;
  5. }
  6. char buf[BUFSIZE]; 
  7.  
  8. struct table_entry entry;
  9.  
  10. entry.length = //The first 4 bytes of buf
  11. entry.offset = //The next 4 bytes of buf
  12. entry.name = //The next 16 bytes of buf
  13.  
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..
Apr 1 '08 #6
MimiMi
42
Expand|Select|Wrap|Line Numbers
  1. struct table_entry{
  2. int length;
  3. int offset;
  4. char *name;
  5. }
  6. char buf[BUFSIZE]; 
  7.  
  8. struct table_entry entry;
  9.  
  10. entry.length = //The first 4 bytes of buf
  11. entry.offset = //The next 4 bytes of buf
  12. entry.name = //The next 16 bytes of buf
  13.  
My problem is the comments, what should the code look like there?
Maybe you can do it like this?
Expand|Select|Wrap|Line Numbers
  1. memcpy(entry.length,buf,4);
  2. memcpy(entry.offset,buf+4,4);
  3. memcpy(entry.name,buf+8,16);
Cheers!
Apr 1 '08 #7
mmk
19
Maybe you can do it like this?
Expand|Select|Wrap|Line Numbers
  1. memcpy(entry.length,buf,4);
  2. memcpy(entry.offset,buf+4,4);
  3. 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.

Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2.  
  3. #define BUFSIZE 100
  4.  
  5. char buf[BUFSIZE][BUFSIZE]={ 1,3,"Trying",2,4,"out",4,5,"something"};
  6.  
  7. struct table_entry{
  8. int length;
  9. int offset;
  10. char *name;
  11. }
  12.  
  13. struct table_entry *tablearray = NULL;
  14. memset(tablearray,0,BUFSIZE);
  15. tablearray = (table_entry*)malloc(sizeof(BUFSIZE));
  16.  
  17. int main()
  18. {
  19.     int i;
  20.     for(i=0;i<BUFSIZE;i++)
  21.     {
  22.         memcpy(tablearray.length,buf,4);
  23.         memcpy(tablearray.offset,buf+4,4);
  24.         memcpy(tablearray.offset,buf+16,16);
  25.     }
  26.     return 0;
  27. }
  28.  
Thanks in advance,
mmk
Apr 1 '08 #8
MimiMi
42
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
Expand|Select|Wrap|Line Numbers
  1. struct table_entry {
  2.   int length;
  3.   int offset;
  4.   char name[NAMESIZE];
  5. };
instead of 'char *name'. And I didn't need an 'intermediate' buffer but could get the struct-data 'straight away'. Kinda like this (pseudocode):
Expand|Select|Wrap|Line Numbers
  1. struct table_entry *tablearray;
  2. int TABLESIZE = 64;
  3. int i,offset = 0;
  4. struct table_entry entry;
  5. tablearray = mem_alloc(sizeof (struct table_entry) * TABLESIZE);
  6. read_from_file(file,(unsigned char*)tablearray,offset,TABLESIZE);
Then I could access the data like this
Expand|Select|Wrap|Line Numbers
  1. for(i=0; i<TABLESIZE;i++)
  2. {
  3. entry.len = tablearray[i].len;
  4. entry.offset = tablearray[i].offset;
  5. strncpy(entry.name,tablearray[i].name,NAMESIZE);
  6. }
Again, thank you all, and take care!
Cheers!
Apr 1 '08 #9
weaknessforcats
9,207 Expert Mod 8TB
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:
Expand|Select|Wrap|Line Numbers
  1. struct data
  2. {
  3.    char* name;
  4. };
  5.  
  6. char buffer[SOMESIZE];
  7. struct data var;
  8. var.data = (char*)malloc((strlen(buffer) + 1) * sizeof(char));
  9. strcpy(var.data, buffer);
  10.  
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.

char buf[BUFSIZE][BUFSIZE]={ 1,3,"Trying",2,4,"out",4,5,"something"};
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.
Apr 1 '08 #10

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

19 posts views Thread by Johnny Google | last post: by
14 posts views Thread by SD | last post: by
31 posts views Thread by aarklon | last post: by
AdrianH
5 posts views Thread by AdrianH | last post: by
AdrianH
1 post views Thread by AdrianH | last post: by
reply views Thread by NPC403 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.