Jump to content
  • Advertisement
Sign in to follow this  

storing std::string on disk

This topic is 4436 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i want to store game information on disk, in a binary file. unfortunately, i don't know the internal structure of an std::string. will storing it on file be a problem?, considering the length of a string can vary, etc? I know if i give it a buffer that is concievebly big enough, it wont overrun the buffer, but will the information be stored/retrieved correctly? for file input/output im using fstreams. thanks for your help guys!

Share this post


Link to post
Share on other sites
Advertisement
Why cant you just do this. Check for errors and correct opening of files of course.


std::string foo = "foobar"
std::string bar;

std::ofstream output("mysavefile.txt");

output << foo;

std::ifstream input("mysavefile.txt");

input >> bar;

Share this post


Link to post
Share on other sites
you can store the raw character array if you can guarantee that your string has no nul character is it('\0').

If it does, you can just write an int out first, its size, followed by the character array...

Share this post


Link to post
Share on other sites
the most important piece to this is that it is a BINARY file.

in that, it is nothing but an array of bytes.

seekg
readg

are the methods that i am using here. in that, if i pass it a buffer of 100 bytes, just to be safe (assuming the the name is very small), will the contents of the string be preserved, because a dynamic char array (char*) is only four bytes. but the name itself could actually be 20 bytes... etc. see what im saying?

Share this post


Link to post
Share on other sites
The general problem you're trying to solve is called "serialization". You want to serialize your game state to a stream (disk) such that you can later de-serialize (inflate) that stored state to new objects.

Using operator<<() is one way of serializing, although it's not guaranteed to support de-serialization (there are no string delimiters output to a standard text output, for example).

Share this post


Link to post
Share on other sites
Quote:
Original post by xSKOTTIEx
see what im saying?


Don't try to save the object itself as a binary blob, it won't work. People who try to blit (as a byte array) non-trivial types (e.g. non-POD) all over the place should be shot. You need to save each data member individually, possibly saving its own data members individually, etc.

You must take care of saving the data it contains instead if necessary). Whether you save it as a fixed-size field in the file, or whether you want to deal with the variable string length is entirely up to you. In both cases, you will have to deal with overflow prevention:

* fixed-width: writes can overflow the field in the file.
* variable-width: reads can overflow the preallocated buffer in the string object.

Decide one way or the other and take the time to do it right or use a serialization librar, like the one found in Boost.

Share this post


Link to post
Share on other sites
I actually wrote a little class to handle reading and writing strings, etc, to a file in both binary and text modes. Take a lookie if you want. Its pretty straight forward to use. It is all templated functions, so its reasonably diverse.

Share this post


Link to post
Share on other sites
A couple things of note. std::string is not null terminated. It is not even vaguely safe to write the std::string directly to file (meaning fwrite or ostream::write). Using the insertion operator with an ostream won't tell you how long the string is. The best way to do this is to write the string to disk (using string::data() rather than string::c_str()), preceded by a 7 bit encoded length. Then when you're reading the string back, you can read into a temporary buffer and then construct a string from it.

This of course assumes that you only ever use ASCII strings.

Share this post


Link to post
Share on other sites
Quote:
Original post by Promit
A couple things of note. std::string is not null terminated. It is not even vaguely safe to write the std::string directly to file (meaning fwrite or ostream::write). Using the insertion operator with an ostream won't tell you how long the string is. The best way to do this is to write the string to disk (using string::data() rather than string::c_str()), preceded by a 7 bit encoded length. Then when you're reading the string back, you can read into a temporary buffer and then construct a string from it.

This of course assumes that you only ever use ASCII strings.


I've never had problems with just writting in ofstream << string << endl;

just put a /n at at the end of each line, then you can read each one easily with getline().


But overall if you want to do some stuff where your want to read and write dynamic text of different sizes, use a (2) flat files system, the first file will contain and index, offset, and possibly the text size. While the second files contain's only the text.

bascially you would read the first index file, get the offset and the length, then read the text in from the second file, that way the first file can be binary and read/write easily with structures that will grab that dynamic text offset's of the other file. Alot of message systems / forums work this way.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!