Sign in to follow this  
cdxrd

Using fstream to read & display data in a struct...

Recommended Posts

Alright, been perusing through some books tonite since I have decided to store some of my preferences and high scores and all in a file in the game directory. Ive got some code I managed to come up with that properly saves the data and can read it back in, but maybe im just not displaying the info right... Heres the code:
#include <fstream>
#include <string>
#include <iostream>

using namespace std;

int myexit = 0;
int menu();
int numElements = 6;
void writefile();
void readfile();

struct pref
{
	string setting;
	int value;
};

ostream& operator << (ostream& str_out, pref& d)
{
	str_out << d.setting << endl;
	str_out << d.value << endl;
	return(str_out);
};

istream& operator >> (istream& str_in, pref& d)
{
	str_in >> d.setting;
	str_in >> d.value;
	return (str_in);
}

int main()
{
	while (myexit < 3)
	{
		int choice = menu();
		if(choice == 3)
		{
			myexit = 3;
		}
		if(choice == 1)
		{
			writefile();
		}
		if(choice == 2)
		{
			readfile();
		}
	}
	return (0);
}

int menu()
{
	int x;
	cout << endl << "Please Select" << endl << "_____________" << endl 
        << endl << "1) Write File" << endl << "2) Read File" << endl 
        << "3) Quit" << endl << endl << "? : ";
	cin >> x;
	return (x);
}


void writefile()
{
	struct pref preferences[6] = 
	{
		{"VideoMode",1},
		{"MusicVolume",1},
		{"EffectVolume",1},
		{"TopScore1",25},
		{"TopScore2",20},
		{"TopScore3",10}
	};
	int x;
	char filename[20] = "prefs.dat";
	int mode = (ios::out | ios::binary);

	fstream fout(filename, mode);
	for (x = 0; x < numElements; x++)
	{
		fout << preferences[x];
	}
	fout.close();

	cout << "Data written to file..." << endl;
}

void readfile()
{
	char filename[20] = "prefs.dat";
	struct pref preferences;
	int mode = (ios::in | ios::binary);

	fstream fin(filename, mode);
	if(!fin)
		cerr << "unable to open file!";

	cout << endl;
	while (fin >> preferences)
	{
		cout << preferences;
	}
	cout << endl << endl << "____________________________________" << endl << endl;

	int x;
	for (x = 0; x < numElements; x++)
	{
		cout << "Setting : ";
		cout << preferences.setting;
		cout << " -=- ";
		cout << preferences.value;
		cout << endl;
	}

	cout << endl;

	fin.close();
}


Now, It saves it properly and it even loads and displays it as it loads properly. But what I need is to be able to display the contents of the struct itself, basically walking through it one element at a time and displaying the setting and the value. Obviously Im doing something wrong, but what?

Share this post


Link to post
Share on other sites
Its stored in the prefs.dat file like this:

VideoMode
1
MusicVolume
1
EffectVolume
1
TopScore1
25
TopScore2
20
TopScore3
10

And this is the way I would prefer to be able to display it:

VideoMode -=- 1
MusicVolume -=- 1
EffectVolume -=- 1
TopScore1 -=- 25
TopScore2 -=- 20
TopScore3 -=- 10

Mind you this is just for my testing and understanding of it. I wont need to display it in the game itself, I will just need to be able to read in and set different values based on whats stored. That part I will work on later.. =) My first game shall have saveable preferences, high scores, the whole 9 yards.. lol.. the gameplay is pretty much already done and works, just adding in options and credits, menu, title screen etc now, and this is the next step.

Share this post


Link to post
Share on other sites
So, something like

std::ostream& operator<<(std::ostream& os, const pref& p)
{
os << p.setting << " -=- " << p.value << std::endl;
return os;
}

std::istream& operator>>(std::istream& is, pref& p)
{
is >> p.setting;
is.ignore(5); // skips over " -=- "
is >> p.value;
return is;
}


Also note the existence of the std::ws manipulator that will skip over leading whitespace, which is sometime useful to do explicitely.

Share this post


Link to post
Share on other sites
I think the way its saved will work fine, I probably should have reworded it better maybe. Once its saved and then loaded back in (I assume the code I posted is loading it correctly into that struct), how can I walk the items in the struct one by one and display them on the screen so that I can see each was loaded properly?

Share this post


Link to post
Share on other sites
How about doing it in the while loop?

void readfile()
{
char filename[20] = "prefs.dat";
struct pref preferences;
int mode = (ios::in | ios::binary);

fstream fin(filename, mode);
if(!fin)
cerr << "unable to open file!";

cout << endl;
while (fin >> preferences)
{
cout << preferences;

cout << "Setting : ";
cout << preferences.setting;
cout << " -=- ";
cout << preferences.value;
cout << endl;
}
cout << endl << endl << "____________________________________" << endl << endl;

fin.close();
}




As far as I can see you are not saving your pref structs.
You read one at a time into the preferences variable.
When the while loop is done, all you have is the last pref struct read from the file in the preferences variable.

If you want to write it after reading it all from file, Id sugges saving them in a vector:

void readfile()
{
char filename[20] = "prefs.dat";
struct pref preferences;
vector<pref> vec_prefs;

int mode = (ios::in | ios::binary);

fstream fin(filename, mode);
if(!fin)
cerr << "unable to open file!";

cout << endl;
while (fin >> preferences)
{
vec_prefs.push_back(preferences);
}
cout << endl << endl << "____________________________________" << endl << endl;

fin.close();

for(int i=0; i<vec_prefs.size(); i++)
{
// Use the << operator you wrote earlier to print the settings
cout << vec_prefs[i];

// Extract and print the settings manually
cout << "Setting : ";
cout << vec_prefs[i].setting;
cout << " -=- ";
cout << vec_prefs[i].value;
cout << endl;
}
}


Share this post


Link to post
Share on other sites
Thanks much for the help! I think this is what I was looking for. I had already started throwing out the readfile() code I had and was rewriting it to store it into an array. But I think a vector would work much better for this. I should have thought about that solution already since I'm using what I learned of vectors in my game right now.. Thanx for all the help!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this