Problem with save mechanisms

Started by
8 comments, last by ferrous 8 years, 5 months ago

Hi, I should call myself a beginer...
I started creating this "game" not so long ago, but I recently thought "Hey, why my game has no save mechanism??!"
And so I found one with fin>> and fout<<, that uses *.save

The problem is... This mechanism is not saving properly!

I tried to do everything I know should help, but nothing worked :/
So yeah, there is the code:


#include <iostream>
#include <conio.h>
#include <windows.h>
#include <cstdlib>
#include <ctime>
#include <accctrl.h>
#include <fstream>

using namespace std;

int main()
{
	  string charactername, gender;                 ////
	string characterclass;                                  ////
	unsigned int w, characterage, xp, lvl, a;                 ////                  Info bout the player's character
	unsigned int hpmax, hp, mpmax, mp, ad, cs, armor;     ////
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	string agree;                                         ////
	unsigned int i, achieve;                                       //// 
	xp=0; lvl=1;                                          ////                   Other thingies
    hpmax=100; hp=100; mpmax=0; mp=0; hp=100; mp=0; ad=5; cs=0; armor=0; achieve=0;              ////
      
	  cout<<"Load a saved file or start a new game?(L/N)\n";
      char choice;
      cin>>choice;
      if (choice=='L')
      {
             string file;
             cout<<"Enter the name of your file: \n";
             cin>>file;
             ifstream fin((file+".save").c_str(), ios::binary);
             fin>>charactername; Sleep (100);
			 fin>>gender; Sleep (100);
			 fin>>characterclass; Sleep (100);
			 fin>>characterage; Sleep (100);
			 fin>>xp; Sleep (100);
			 fin>>lvl; Sleep (100);
			 fin>>hpmax; Sleep (100);
			 fin>>hp; Sleep (100);
			 fin>>mpmax; Sleep (100);
			 fin>>mp; Sleep (100);
			 fin>>ad; Sleep (100);
			 fin>>cs; Sleep (100);
			 fin>>armor; Sleep (100);
			 fin>>achieve;
			 
             cout<<" The name of the character: "<<charactername<<endl; Sleep (100);
			 cout<<" The gender of the character: "<<gender<<endl; Sleep (100);
			 cout<<" The class of the character: "<<characterclass<<endl; Sleep (100);
			 cout<<" The age of the character: "<<characterage<<endl; Sleep (100);
			 cout<<" The xp level of the character: "<<xp<<endl; Sleep (100);
			 cout<<" The level of the character: "<<lvl<<endl; Sleep (100);
			 cout<<" The max ammount of the character's hp: "<<hpmax<<endl; Sleep (100);
			 cout<<" The last ammount of the character's hp: "<<hp<<endl; Sleep (100);
			 cout<<" The max ammount of the character:'s mp: "<<mpmax<<endl; Sleep (100);
			 cout<<" The last ammount of the character's mp: "<<mp<<endl; Sleep (100);
			 cout<<" The value of attack damage of the character: "<<ad<<endl; Sleep (100);
			 cout<<" The critical chance of the character: "<<cs<<endl; Sleep (100);
			 cout<<" The armour of the character: "<<armor<<endl; Sleep (100);
			 cout<<" The value of the character's progress in the game: "<<achieve<<endl; system ("PAUSE");
             switch (achieve)
             {
			 	case 0:
			 		goto launch;
			 		break;
			 	case 1:
			 		goto acceptedID;
			 		break;
			 }
			 system ("PAUSE");
             }
      
      achieve=0;
	  launch:
	  do
	{
    system ("CLS");
    cout<<achieve;
	cout<<"\n What's your name?\n ";
	cin>>charactername;
	
	cout<<"\n What is your gender, "<<charactername<<"?\n"; 
	do
	{
	cout<<" [M/F] ";
	cin>>gender;
	if (gender !="M" && gender !="F") cout<<"\n Give me the proper answer!\n";
	} while (gender !="M" && gender !="F");
	
	cout<<"\n Welcome, "; if (gender=="M") cout<<"gentleman"; else cout<<"milady"; cout<<".\n May I ask how old are you?\n"; 
	do
	{
	cout<<" [16-50] ";
	cin>>characterage;
	if (characterage <= 15 || characterage >= 51) cout<<"\n Give me the proper answer!\n";
	} while (characterage <= 15 || characterage >= 51);
    
	cout<<"\n\n Chose your class, "<<charactername<<".";
    cout<<"\n\n [1] "; if (gender=="F") cout<<"Warrioress"; else cout<<"Warrior"; cout<<"\n";
    cout<<"\n [2] "; if (gender=="F") cout<<"Sorceress"; else cout<<"Mage"; cout<<"\n";
    cout<<"\n [3] Assassin\n\n\n [1/2/3] ";
    do
	{
    cin>>a; if (a != 1 && a != 2 && a != 3) cout<<"Give me the proper answer!\n";
	} while (a != 1 && a != 2 && a != 3);
	switch (a)
	{
		
		case 1:
        if (gender=="F") characterclass="Warioress"; else characterclass="Warrior";
        	break;
        
        case 2:
  	    if (gender=="F") characterclass="Sorceress"; else characterclass="Mage";
        	break;
        	
        case 3:
  	    characterclass="Assassin";
  	    
	}
    
    acceptedID:
    
	cout<<"\n So... Your name is "<<charactername<<", you are "<<characterage<<" years old and your class is "<<characterclass; cout<<"\n\n";
	cout<<"\n Is everything alright?\n"; do {cout<<" [Y/N] "; cin>>agree;} while (agree !="Y" && agree !="N");
	if (agree=="T") {cout<<"\n\n Ok then, good luck and have fun!\n"; achieve=achieve+1; cout<<achieve;}
	cout<<" Do you want to save & exit now?\n";
	cout<<" [Y/N] ";
	cin>>agree;
	if (agree=="Y") goto end;} while (agree !="T");
	
	/// Rest of the game
	
      end:
      cout<<"\n\nYou chose to exit. Do you wish to save your current progress\n\
      to continue the game later?(Y/N) ";
      cin>>choice;
      if (choice=='Y')
      {
             string save;
             cout<<"Enter the name of the file in which you want to save your progress: \n";
             cin>>save;
             ofstream fout((save+".save").c_str(), ios::binary);
             
			 fout<<characterclass;
			 fout<<xp;
			 fout<<lvl;
			 fout<<gender;
			 fout<<hpmax;
			 fout<<hp;
			 fout<<charactername;
			 fout<<mpmax;
			 fout<<mp;
			 fout<<ad;
			 fout<<cs;
             fout<<characterage;
             fout<<armor;
			 fout<<achieve;
             }
      
    stop:
	cout<<"\n\n\n____________\n DEAD END, "<<"\n\n You earned "<<xp<<" xp, and "<<lvl<<" level!";
	while (!kbhit());
      
      }

Also, two photos

On the 1st one you can see what I put in at first
On the 2nd one is what I've got when I tried to Load the save

Btw english is not my first language, as you may have spotted... I translated this all so it will be easier for you to understand.
I'll be really thankful for any advice smile.png

Advertisement

Make sure you read and write the savefile in same order, or youll get garbage.

o3o

If you mean saving and writing loading variables in same order - it doesnt work. If you mean something else - I didn't understand, sorry.


If you mean saving and writing loading variables in same order - it doesnt work. If you mean something else - I didn't understand, sorry.

In the code you posted, you save and load variables in a completely different order. That's completely broken:


            fin>>charactername; Sleep (100);
			 fin>>gender; Sleep (100);
			 fin>>characterclass; Sleep (100);
			 fin>>characterage; Sleep (100);
			 fin>>xp; Sleep (100);
			 fin>>lvl; Sleep (100);
			 fin>>hpmax; Sleep (100);
			 fin>>hp; Sleep (100);
			 fin>>mpmax; Sleep (100);
			 fin>>mp; Sleep (100);
			 fin>>ad; Sleep (100);
			 fin>>cs; Sleep (100);
			 fin>>armor; Sleep (100);
			 fin>>achieve;

			 fout<<characterclass;
			 fout<<xp;
			 fout<<lvl;
			 fout<<gender;
			 fout<<hpmax;
			 fout<<hp;
			 fout<<charactername;
			 fout<<mpmax;
			 fout<<mp;
			 fout<<ad;
			 fout<<cs;
             fout<<characterage;
             fout<<armor;
			 fout<<achieve;

As far as I can see your loading and saving are not identical:


             ifstream fin((file+".save").c_str(), ios::binary);
             fin>>charactername; Sleep (100); // name is loaded first, but class is saved first, etc.
			 fin>>gender; Sleep (100); // you don't need these Sleep() either
			 fin>>characterclass; Sleep (100);
			 fin>>characterage; Sleep (100);
			 fin>>xp; Sleep (100);
			 fin>>lvl; Sleep (100);
			 fin>>hpmax; Sleep (100);
			 fin>>hp; Sleep (100);
			 fin>>mpmax; Sleep (100);
			 fin>>mp; Sleep (100);
			 fin>>ad; Sleep (100);
			 fin>>cs; Sleep (100);
			 fin>>armor; Sleep (100);
			 fin>>achieve;

             ofstream fout((save+".save").c_str(), ios::binary);
             
			 fout<<characterclass;
			 fout<<xp;
			 fout<<lvl;
			 fout<<gender;
			 fout<<hpmax;
			 fout<<hp;
			 fout<<charactername;
			 fout<<mpmax;
			 fout<<mp;
			 fout<<ad;
			 fout<<cs;
             fout<<characterage;
             fout<<armor;
			 fout<<achieve;

Also, >> reads until whitespace (and maybe some other characters), so if your class or name or something else contains spaces it will not load the way you expect it to.

Just noticed that you have ios::binary flag set. I'm not sure how it works when writing strings using << and >>, but try to remove it, since your file isn't really binary.

More things you can try:

Try to open savefile manually and confirm visually whether it saved what you expected.

I assume you are using Visual Studio; try to play with debugger to see what gets loaded after each statement.

They are identical now, but nothing really changed (as seen on pictures below

12178202_1667647996824259_1382180042_n.j

12178091_1667648000157592_1432517168_n.j

I tried removing ">>" and "<<", not working
Removing flag doesn't work too

Save file...
There is nothing but "character's name" inside
I mean
I opened file from my the beggining of my post, and it shows "Warioress01F100100Zelinda00501800", which is exactly same as what my program gave me with fin>>charactername

The stream read operation uses whitespace as a delimiter. You'll need to write something like a newline character between fields to read them back one by one. This will also allow you to use std::getline() for strings, thus allowing you to save strings with embedded space characters.

You'll need to separate your fields with whitespace. Otherwise, there would be no distinguishing between {1, 2, and 3} and {123, uninitialized, uninitialized}:

fout	<<characterclass << ' '
	<<xp << ' '
	<<lvl << ' '
	<<gender << ' '
	<<hpmax << ' '
	<<hp << ' '
	<<charactername << ' '
	<<mpmax << ' '
	<<mp << ' '
	<<ad << ' '
	<<cs << ' '
;
EDIT;
Ninja'd

I added endlines wherever "fout<<" was... and it worked! ^^

Thank you all so much! biggrin.png

I highly recommend just outputting as text when just starting. You can always flip to binary later. Then you can eyeball your output, and tweak numbers manually as well.

This topic is closed to new replies.

Advertisement