Data Structure File I/O

Started by
16 comments, last by elis-cool 21 years, 11 months ago
OK so I have a Linked List and what I want to do is save each of the nodes (as they hold their own data) into the same file, how would I go about this, and also load them back into nodes when the program is run again? via this method (possibly, unless you know better...): File.write((char*)this, sizeof(*this)); File.read((char*)this, sizeof(*this)); // inside member functions... CEO Plunder Studios
[email=esheppard@gmail.com]esheppard@gmail.com[/email]
Advertisement
Sounds good and basic.
But maybe for error-checking you should check into having a header or just an INT to tell you how many data items are included. At this stage it''s too early to worry about a compression scheme.

ZoomBoy
Developing a iso-tile 2D RPG with skills, weapons, and adventure. See my old Hex-Tile RPG GAME, character editor, diary, 3D Art resources at Check out my web-site
Yeah but how do you write it so each node is stored after the last in the file sort of thing? and how do you load them back into the nodes correctly? since the nodes would have the *myNext pointer which would then be loaded into the nodes again and would be pointing to the wrong memory addresses...

CEO Plunder Studios
[email=esheppard@gmail.com]esheppard@gmail.com[/email]
Assuming your structs are declared something like this:
struct Link {  // data  char data[100];  Link *next;}; 

If you know the size of ''data'', you can do:
Link *pLink = ...;write(pLink->data, 100); 

Another way [relies on ''next'' member being the last]:
Link *pLink = ...;write(pLink, sizeof *pLink-sizeof pLink); 

Or you could just write each ''Link'' data member individually:
write(pLink->data1, sizeof pLink->data1);write(pLink->data2, sizeof pLink->data2); 

Or you can use std::list:

  std::list <Data> aList;// fill aListData data = *aList.begin();write(data, sizeof data);  

Reverse this for reading.
---visit #directxdev on afternet <- not just for directx, despite the name
Don''t load (or save) the pointers to the next node... Just traverse the list saving the values then just incert them in order they are found in the file -> let the list rebuild itself.

- mongrelprogrammer
- I hate these user ratings. Please rate me down. (Seriously) -
quote:Original post by mongrelprogrammer
Don''t load (or save) the pointers to the next node... Just traverse the list saving the values then just incert them in order they are found in the file -> let the list rebuild itself.

- mongrelprogrammer

Well it holds more than one value... eg, strings, int''s, and they are of varing size''s...
At the moment everything is stored in the node class so I might make a seperate data class and when the program starts up add a new node to the list and have it point to the loaded Data class... any more ideas...



CEO Plunder Studios
[email=esheppard@gmail.com]esheppard@gmail.com[/email]
If your strings are of varying size then you could always save the size of the string as well and read the size and use that to properly read the string.

I will not make a list of links... I will not make a list of links... I will not make a list of links...
Invader''s Realm
*Ahem*

You cannot arbitrarily save objects in binary format.

You can''t just use fwrite to save your data if your data objects contains pointers (you would just save the address, not the data, which would be completely useless), or if the data object has virtual functions (hence possibly a vtbl pointer), requires a constructor (which wouldn''t be called when restoring the object)...

In short, if it is not Plain Old Data (i.e. C structure), you will have to save your objects member by member (e.g. create an adequate ostream& operator<<( ostream& os, const Data&)


Assuming you have such an operator, you can just write, to save the data in ascii form

#include <list>        // header for list#include <iterator>    // header for (i/o)stream_iterator#include <algorithm>   // header for copy#include <fstream>     // header for (i/o)fstreamusing namespace std;list theList;ofstream ofs( "OutFile" ); // file stream to saveifstream ifs( "InFile" ); // file stream to load// savecopy( theList.begin(), theList.end(), ostream_iterator<Data>(ofs, '' '' ) );// loadtheList.assign( istream_iterator<Data>(ifs), istream_iterator<Data>() ); 


To save it in binary form, you will have to come up with your own function loading one object from a binary stream (similar to fread, but taking the object''s specificities into account) and combine it with algorithms like std::generate.

[Questions (STFW) | GDNet Start Here | GDNet Search | Forum FAQ | Google | Asking Smart Questions ]
[Docs (RTFM) | MSDN | SGI''s STL | OpenGL | File formats]
[C++ Must Haves (RTFS) | MinGW | Boost | Loki | FLTK | SDL ]

Stolen from Magmai Kai Holmlor, who held it from Oluseyi, who was inspired by Kylotan...
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Well I dont really want to write in text mode (possible sensitive info)...

But if I have to I could encrypt it... and have something like so saved to a file:
Start username
name
value
...
End
Start username
name
value
...
End
Or something and just read the file cheaking for the key word Start for where the next nodes data begins... this may be too slow for a large file...
Or I could just have a:
struct Data{string name;int val;...}; 

and then have each node point to one of these that holds its data and just create a new node for each file it finds for the nodes and assign (ie. have a pointer) the Data to a new node...
but then if theres alot of nodes there may be way to many files in the directory...



CEO Plunder Studios
[email=esheppard@gmail.com]esheppard@gmail.com[/email]
You can try this: Serialization and Deserialization chapter from Bartosz Milewski''s online book. There is some theory and code examples of data structure saving and loading.

This topic is closed to new replies.

Advertisement