-
Problems with ofstream
Hi. I'm trying to use ofstream to save the data for the game I'm coding, but I've hit a snag. When it saves the game, for some reason it outputs a null character to the start of the file, meaning that it can't load again properly. clear() and pause(1) are functions that I wrote to clear the screen and wait for any key, respectively, and they work fine. The saveto << line is just broken up so that it wraps right here, it's all one line in the code.
Code:
int save()
{
clear();
cout<<"Saving game...\n";
ofstream saveto ( "stockmarket.sav" ); //Open file to save to and input data, comma-delimited
saveto.seekp ( 0 );
saveto << playername <<","<< cash <<","<< boom <<","<< recession <<","<< gi <<","<< gic <<","<< paid <<","<< week <<
","<< gamelength <<","<< stock[0] <<","<< stock[1] <<","<< stock[2] <<","<< stock[3] <<","<< stock[4] <<","<< stock[5] <<
","<< stock[6] <<","<< stock[7] <<","<< stock[8] <<","<< stock[9] <<","<< value[0] <<","<< value[1] <<","<< value[2] <<
","<< value[3] <<","<< value[4] <<","<< value[5] <<","<< value[6] <<","<< value[7] << ","<< value[8] <<","<< value[9];
saveto.close(); //Close save file
cout<<"Game saved successfully!\n";
pause(1);
}
-
Well if you are looking to clear a file each time you open it for a write you can use ios::trunc and just write to the file normally and it will start at the begining.
-
-
-
Same as the last time, but with
Code:
ofstream saveto ( "stockmarket.sav" );
replaced with
Code:
ofstream saveto ( "stockmarket.sav" , ios::trunc );
-
Remove that seekp(0); and see what happens.
Code:
#include <iostream>
#include <fstream>
#include <string>
struct player
{
std::string name;
int money;
int str;
int def;
};
int main()
{
player mainP;
std::ofstream toSave("player.sav",std::ios::trunc);
mainP.name = "Brian";
mainP.money = 1000;
mainP.str = 10;
mainP.def = 10;
toSave<<mainP.name<<std::endl
<<mainP.money<<std::endl
<<mainP.str<<std::endl
<<mainP.def<<std::endl;
toSave.close();
return 0;
}
Output
-
Still has the same problem.
-
Well are you sure it is not how you are reading the file in. Because if you are doing what you said the output should be correct.
-
Well, I was opening the output file in a good text editor, and it clearly printed the null character at the start of the file. But just in case, here is the loading half of the equation:
Code:
int load()
{
ifstream temp("stockmarket.sav");
if(!temp.is_open())
{
cout<<"\nNo save file present.\n";
pause(1);
return -1;
}
else
{
cout<<"\n";
FILE * pFile;
long lSize;
char * buffer;
char * output;
int count = 0;
pFile = fopen ( "stockmarket.sav" , "rb" );
if (pFile==NULL) exit (1);
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
buffer = (char*) malloc (lSize);
if (buffer == NULL) exit (2);
fread (buffer,1,lSize,pFile);
output = strtok(buffer,",");
do
{
if ( output != NULL )
{
switch ( count )
{
case 0:
playername = output;
break;
case 1:
cash = atoi( output );
break;
case 2:
boom = atoi( output );
break;
case 3:
recession = atoi( output );
break;
case 4:
gi = atoi( output );
break;
case 5:
gic = atoi( output );
break;
case 6:
paid = atof( output );
break;
case 7:
week = atoi( output );
break;
case 8:
gamelength = atoi( output );
break;
case 9:
stock[0] = atoi( output );
break;
case 10:
stock[1] = atoi( output );
break;
case 11:
stock[2] = atoi( output );
break;
case 12:
stock[3] = atoi( output );
break;
case 13:
stock[4] = atoi( output );
break;
case 14:
stock[5] = atoi( output );
break;
case 15:
stock[6] = atoi( output );
break;
case 16:
stock[7] = atoi( output );
break;
case 17:
stock[8] = atoi( output );
break;
case 18:
stock[9] = atoi( output );
break;
case 19:
value[0] = atoi( output );
break;
case 20:
value[1] = atoi( output );
break;
case 21:
value[2] = atoi( output );
break;
case 22:
value[3] = atoi( output );
break;
case 23:
value[4] = atoi( output );
break;
case 24:
value[5] = atoi( output );
break;
case 25:
value[6] = atoi( output );
break;
case 26:
value[7] = atoi( output );
break;
case 27:
value[8] = atoi( output );
break;
case 28:
value[9] = atoi( output );
break;
}
}
output = strtok (NULL, ",");
count++;
}while ( output != NULL );
fclose (pFile); //Close file and clear buffer
free (buffer);
}
screen();
}
-
I am not the best person on reading in a certain type of input. But I can tell you that it I would not mix C and C++ file streams. As far as you code I think that this would work the same as above.
Code:
int load()
{
long lSize;
char * buffer = NULL;
char * output = NULL;
int count = 0;
ifstream temp("stockmarket.sav", ios::binary);
if(!temp.is_open())
{
cout<<"\nNo save file present.\n";
pause(1);
return -1;
}
else
{
cout<<"\n";
temp.seekg(0,ios::end);
lSize = temp.tellg();
temp.seekg(0,ios::beg);
buffer = new char[lSize];
if (buffer == NULL)
{
exit (2);
}
temp.read(buffer,lSize);
output = strtok(buffer,",");
do
{
if ( output != NULL )
{
switch ( count )
{
case 0:
playername = output;
break;
case 1:
cash = atoi( output );
break;
case 2:
boom = atoi( output );
break;
case 3:
recession = atoi( output );
break;
case 4:
gi = atoi( output );
break;
case 5:
gic = atoi( output );
break;
case 6:
paid = atof( output );
break;
case 7:
week = atoi( output );
break;
case 8:
gamelength = atoi( output );
break;
case 9:
stock[0] = atoi( output );
break;
case 10:
stock[1] = atoi( output );
break;
case 11:
stock[2] = atoi( output );
break;
case 12:
stock[3] = atoi( output );
break;
case 13:
stock[4] = atoi( output );
break;
case 14:
stock[5] = atoi( output );
break;
case 15:
stock[6] = atoi( output );
break;
case 16:
stock[7] = atoi( output );
break;
case 17:
stock[8] = atoi( output );
break;
case 18:
stock[9] = atoi( output );
break;
case 19:
value[0] = atoi( output );
break;
case 20:
value[1] = atoi( output );
break;
case 21:
value[2] = atoi( output );
break;
case 22:
value[3] = atoi( output );
break;
case 23:
value[4] = atoi( output );
break;
case 24:
value[5] = atoi( output );
break;
case 25:
value[6] = atoi( output );
break;
case 26:
value[7] = atoi( output );
break;
case 27:
value[8] = atoi( output );
break;
case 28:
value[9] = atoi( output );
break;
}
}
output = strtok (NULL, ",");
count++;
}while ( output != NULL );
}
screen();
}
I am not sure if this will work completely. I am sure someone else here knows more about C++ filestream tokenizing than me.
-
What header files do I need for that? And what is the is. stuff for?
-
Whoops. I meant temp. You would include <fstream> and that should be it. If you wanted to get even more C++ you could use stringstream instead of atoi.
-
Are you sure your playername variable does not have something on the front of it?
-
Apparently, it can't identify the c_str() function...
-
My bad agian. I was going to use a string but decided on a char * so just remove the c_str().
-
*sigh* Nope, still not working. This is starting to irritate me..
-
Oh god. You're going to hate me.
I just found out what's wrong. It turns out that when I changed the input method for the playername variable, I screwed it up. The file was outputting properly, its just that the first character of the variable was NULL.
Well, thanks for the help, at least it'll show in the archives for if any new guys hit problems. And that code you gave me is a lot more efficient. Many tanks.