Save/Load routine failing. some help?

Started by
16 comments, last by Radagar 21 years, 7 months ago
Thanks JohnAD. I was goign that route when you posted, but I wasn''t sure of the format for the fstream class and input/output. Your example helps a lot.

But... I''m a little worried it might not work based solely on your example. My example above worked fine when ran like it was, because the pointers to chars inside the strings that I created were not getting reset. But if you run the part of the code to write the class out to file and close.. then restart and run just the code to read it in, the pointers don''t mean anything and any string part of the class is invalid data.

This may not be a problem when using fstream, I''m going to test it... But your program above doesn''t necessarily prove that it will work since it is writing to the file then reading from it in the same run when the pointers are still valid, as my program above does.

And there is also the possibility that I''m largely confused and don''t know what I''m talking about =)

Thanks for the code though, I''m going to try using fstream and see if it works!



~~~~~~~~~~~
Chris Vogel
~~~~~~~~~~~
WyrmSlayer RPG - In Early Development
Advertisement
Radagar:

I just tested a version that only reads the file, and came up with the same error that you got. One way to work around this would be to create a capatible class that stored the character array, and just copy the values over before saving.

John.

[EDIT] I hate typing while I'm in a hurry...[/EDIT]

[edited by - JohnAD on September 11, 2002 12:03:55 AM]
Yeah...the string pointers are likely causeing the goof.

Some things that you might want to consider:

Make the characters race and class integers that can be used as indexes in the appropriate arrays (define as CONSTants?)...this way you can save further headackes down the road...

say a value of 1 = a ''human''...a 2 = ''ork''...3 = ''elf''...whatever...then in the game if there is anything associated with the class that must be performed (a magic spell that only effects orks, for example) then you can check the race statis of the player useing the value rather then a string...this way there won''t be any suprises if somewhere in your code you missspelled (and/or capitalized) the word ''Ork''.
Same goes for class...

Also...and this would be easy to do

You can keep the class just as it is right now (change race and class to integers, of course)...and still save the file correctly, without errors on loading it back in again.

simply use the name of the character for the name of the file...make the file location something unique (like ''.mysave'' etc..) for all character save files...then you can save the character as is (pointer and all) without problems.

Loading the file back in will be more difficult...first set up a local pointer to a location to temporarily hold the character name...then let the player select the file to load ("*.mysave" to bring up a list of files,etc..)...once selected...read everything in the file name before the ''.'' into the local name string ...then load the file in...then change the file loaded name (which would contain garbage at this point) to the local name...deleate the temporary local name and you are done.

Course there are file name length limitations and such...but you have given the player the ability to then make back-up copies of specific characters-n-such without adding more game code in doing so
D''oh! I didn''t even think of that. Good call MSW!

John.
You could build on this simple (?) sample for reading/writing objects from/to streams. Just overload Read and Write for your specific class (as done for std::string) and it should work fine. It may not be the fastest solution there is.

  #include <iostream>#include <string>// T must not be a pointer nor a struct/class that contains// pointers nor a struct/class that have a vtable (virtual methods).template <class T>bool Write(std::ostream& rStream, const T& rObject){   rStream.write((const char*) &rObject, sizeof(T));   if (!rStream)   {      return false;   }   return true;}// T must not be a pointer nor a struct/class that contains// pointers nor a struct/class that have a vtable (virtual methods).template <class T>bool Read(std::istream& rStream, T& rObject){   rStream.read((char*) &rObject, sizeof(T));   if (!rStream)   {      return false;   }   return true;}bool Write(std::ostream& rStream, const std::string& rString){   size_t   uiSize = rString.size();   if (!Write(rStream, uiSize))   {      return false;   }   for (std::string::const_iterator pIter = rString.begin(), pIterEnd = rString.end(); pIter != pIterEnd; ++pIter)   {      if (!Write(rStream, *pIter))      {         return false;      }   }   return true;}bool Read(std::istream& rStream, std::string& rString){   size_t   uiSize;   if (!Read(rStream, uiSize))   {      return false;   }   rString.resize(uiSize);   for (std::string::iterator pIter = rString.begin(), pIterEnd = rString.end(); pIter != pIterEnd; ++pIter)   {      if (!Read(rStream, *pIter))      {         return false;      }   }   return true;}  
Arguing on the internet is like running in the Special Olympics: Even if you win, you're still retarded.[How To Ask Questions|STL Programmer's Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]
I''ve never worked with templates before, do maybe a stupid question : how would you implement something like that ?
Thanks all! I''ll use the suggestion of making them INT''s and just looking up the string values from an array. That works out better later on as you said.

As for the idea of assigning the name based on the name of the file, that''s pretty good, but it would be harder for the race and class, and it wouldn''t really work with my current design plan. Thanks for the suggestion though!

GameDev is a great community, I can always get help here. Until my next problem, Laters!

~~~~~~~~~~~
Chris Vogel
~~~~~~~~~~~
WyrmSlayer RPG - In Early Development
quote:Original post by jkeppens
I've never worked with templates before, do maybe a stupid question : how would you implement something like that ?

No question is too stupid to ask, only the answers.

Put the code I wrote in a header, include it where you are streaming binary data and do like this for example:

  #include <theheaderwiththestuffiwroteealier.h>class Person{public:   Person(const std::string& rstrName, int iAge)    : mstrName(rstrName),      miAge(iAge)   {   }   Person(std::istream& rStream)   {      if (!Read(rStream, *this))      {         throw std::exception("Failed to construct Person from from stream");      }   }   const std::string& GetName() const { return mstrName; }   int GetAge() const { return miAge; }   void SetName(const std::string& rstrName) { mstrName = rstrName; }   void GetAge(int iAge) { miAge = iAge; }   friend bool Write(std::ostream& rStream, const Person& rPerson);   friend bool Read(std::istream& rStream, Person& rPerson);private:   std::string    mstrName;   int            miAge;};bool Write(std::ostream& rStream, const Person& rPerson){   if (!Write(rStream, rPerson.mstrName))   {      return false;   }   if (!Write(rStream, rPerson.miAge))   {      return false;   }   return true;}bool Read(std::istream& rStream, Person& rPerson){   if (!Read(rStream, rPerson.mstrName))   {      return false;   }   if (!Read(rStream, rPerson.miAge))   {      return false;   }   return true;}int main(){   Person         person1("Dalleboy", 24);   std::ofstream  stream1("c:/person.dat", std::ios::binary);   if (!Write(stream1, person1))   {      std::cerr << "Failed to write person to stream" << std::endl;      return 1;   }   stream1.close();   std::ifstream  stream2("c:/person.dat", std::ios::binary);   Person         person2(stream2);   std::cout << "Name: " << person1.GetName() << ", Age: " << person1.GetAge() << std::endl;   std::cout << "Name: " << person2.GetName() << ", Age: " << person2.GetAge() << std::endl;   return 0;}  


[edited by - dalleboy on September 12, 2002 11:26:48 AM]
Arguing on the internet is like running in the Special Olympics: Even if you win, you're still retarded.[How To Ask Questions|STL Programmer's Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]

This topic is closed to new replies.

Advertisement