C wizards,
If I write a structure to disk using fwrite(), what happens about pointers to structers? does the pointer or what its pointing at get saved?
Thanks
D
__________________________________________________ Do You Yahoo!? Get personalized email addresses from Yahoo! Mail http://personal.mail.yahoo.com/
On 30-Jun-01 David Freeman wrote:
C wizards,
If I write a structure to disk using fwrite(), what happens about pointers to structers? does the pointer or what its pointing at get saved?
Thanks
D
sorry for playing man pages but
<quote>
size_t fwrite( const void *ptr, size_t size, size_t nmemb, FILE *stream);
The function fwrite writes nmemb elements of data, each size bytes long, to the stream pointed to by stream, obtaining them from the location given by ptr.
</quote
so I would suggest that the pointer you put in ptr would not be writtern out but the data it pointed to. I generally deal with text and so this has never been an issue for me. I do warn you that it you do not know your data file sizes in advance for your structure this could get hairy.
I am such an XML biggot that I barely write things that are not XML related, though I just did some text processing to take the track listings from CD's in grip and ~/.cddb and turn them into postscript the correct size for printing using groff for postscript generation.
Owen
Must be asleep this is less than clear Email
Owen
On 01-Jul-01 oms101@freeuk.com wrote:
On 30-Jun-01 David Freeman wrote:
C wizards,
If I write a structure to disk using fwrite(), what happens about pointers to structers? does the pointer or what its pointing at get saved?
Thanks
D
sorry for playing man pages but
<quote>
size_t fwrite( const void *ptr, size_t size, size_t nmemb, FILE *stream);
The function fwrite writes nmemb elements of data, each size bytes long, to the stream pointed to by stream, obtaining them from the location given by ptr.
</quote>
cleaned up text
so I would suggest that the pointer you put in ptr would not be writtern out but the data it pointed to. I generally deal with text and so this has never been an issue for me but I do warn you that if you do not know your data file sizes in advance for your structure this could get hairy.
I am such an XML biggot that I barely write things that are not XML related, though I just did some text processing to take the track listings from CD's in grip and ~/.cddb and turn them into postscript the correct size for printing using groff for postscript generation.
Owen
Date: 01-Jul-01 Time: 01:08:58
On Sat, Jun 30, 2001 at 04:53:58PM -0700, David Freeman wrote:
C wizards,
If I write a structure to disk using fwrite(), what happens about pointers to structers? does the pointer or what its pointing at get saved?
The write function takes a pointer and writes out to disk whatever that pointer points to. You also have to tell it how big that item is.
Imagine you have a structure liek this:
struct recd { name[10]; int some_value; }
If you define a variable of this structure type directly, like this:
struct recd myrecd;
then you need to the use '&' operater to give fwrite a pointer to it, like this:
fwrite(&myrecd, sizeof(myrecd), 1, fp);
If you have a pointer to a structure of this type, like this:
struct recd *myrecptr;
and that pointer points to some valid memory then you can write the structure to disk by calling fwrite with the pointer directly, like this:
fwrite(myrecptr, sizeof(*myrecptr), 1, fp);
Note the '*' in the sizeof operator - we want the size of the thing pointed to (the structure) not the size of the pointer. If you were to make the mistake of using the:
fwrite(&myrecdptr, sizeof(myrecdptr), 1, fp);
form when myrecptr was a pointer then you would indeed write the pointer to the disk instead of the structure pointed too and this is almost never useful.
The other catch you need to be wary of is strings in structures. In the example above I used a fixed length string, so the space for the characters of the string is within the structure. This is fine for short strings but for longer ones it is more usual to have:
struct recd { char *name; int someval; }
In this case all that is store in the structure is a pointer to where the string is actually stored. If you write this kind of structure to disk you would get the pointer to the string written to disk as part of the structure but not the contents of the string.
Steve.
--- Steve Fosdick fozzy@pelvoux.demon.co.uk wrote:
On Sat, Jun 30, 2001 at 04:53:58PM -0700, David Freeman wrote:
C wizards,
If I write a structure to disk using fwrite(), what happens about pointers to structers? does the pointer or what its pointing at get saved?
The write function takes a pointer and writes out to disk whatever that pointer points to. You also have to tell it how big that item is.
I get this bit.
Imagine you have a structure liek this:
struct recd { name[10]; int some_value; }
If you define a variable of this structure type directly, like this:
struct recd myrecd;
then you need to the use '&' operater to give fwrite a pointer to it, like this:
fwrite(&myrecd, sizeof(myrecd), 1, fp);
If you have a pointer to a structure of this type, like this:
struct recd *myrecptr;
and that pointer points to some valid memory then you can write the structure to disk by calling fwrite with the pointer directly, like this:
fwrite(myrecptr, sizeof(*myrecptr), 1, fp);
Note the '*' in the sizeof operator - we want the size of the thing pointed to (the structure) not the size of the pointer. If you were to make the mistake of using the:
fwrite(&myrecdptr, sizeof(myrecdptr), 1, fp);
form when myrecptr was a pointer then you would indeed write the pointer to the disk instead of the structure pointed too and this is almost never useful.
This all makes sense.
The other catch you need to be wary of is strings in structures. In the example above I used a fixed length string, so the space for the characters of the string is within the structure. This is fine for short strings but for longer ones it is more usual to have:
struct recd { char *name; int someval; }
This is exactly what I have, how would I save the contents of this structure? would I have to save the text into another file and then read the struct file in from one place and the text from else where?
In this case all that is store in the structure is a pointer to where the string is actually stored. If you write this kind of structure to disk you would get the pointer to the string written to disk as part of the structure but not the contents of the string.
How would I get the contents of the string?
Thanks
D
Steve.
alug, the Anglian Linux User Group list Send list replies to alug@stu.uea.ac.uk http://www.anglian.lug.org.uk/ http://rabbit.stu.uea.ac.uk/cgi-bin/listinfo/alug See the website for instructions on digest or unsub!
__________________________________________________ Do You Yahoo!? Get personalized email addresses from Yahoo! Mail http://personal.mail.yahoo.com/
on Sun, Jul 01, 2001 at 05:12:18AM -0700, David Freeman scribbled:
struct recd { char *name; int someval; }
This is exactly what I have, how would I save the contents of this structure? would I have to save the text into another file and then read the struct file in from one place and the text from else where?
yes, or you could do fprintf/fgets to write/read the data, this also avoids endianness issues (because it's saved/loaded as binary data with fwrite/fread).. If there is only one string, you can still get away with fwrite/fread though.. but you need to be a bit more careful.
struct recd { int someval; char name[0]; };
and dynamically allocate the structure with sizeof(struct recd) + length of name. fprintf/fgets is much more flexible.
struct rec_t { char *fname; char *sname; int age; } rec[MAX_REC];
to save: { int x;
for (x = 0; x < MAX_REC; x++) { if (fprintf(fd, "%s:%s:%d\n", rec[x].fname, rec[x].sname, rec[x].age) > MAX_LINE) warn("line too long"); /* messy */ } }
to load (assuming you don't want any dynamically allocated line buffers and have a max line length): { char buf[MAX_LINE]; int x,len;
x = 0;
while(x <= MAX_REC && fgets(buf, sizeof(buf), fd) != NULL) { len = strchr(buf, ':') - buf;
if (len < 0) err("invalid record: %d", x);
if ((rec[x].fname = malloc(len + 1)) == NULL) err("malloc failed");
memcpy(rec[x].fname, buf, len); rec[x].fname[len] = '\0';
/* repeat for sname and use atoi on age.. */
x++; } if (!feof(fd)) /* error */ return -1; return 1; }
warn(), err() being error spouting functions.. This may not work (small errors in code), but that's basically how I'd do it.. You also need to remember to free() stuff. Yes, you could use fscanf instead of fgets, but then parsing strings containing spaces is harder and dynamically allocating enough memory for strings more troublesome.