Writing variables to a text file

Hello,

I'm new to C++ and I'm trying to write two variables to a text file. They are basically a players name and their score but formatted as shown.

The text file consists of 3 tab spaces, then a name, a comma, a space, then a number. i.e:

Test1, 10
Test2, 30
Test3, 50

(tabs aren't showing for some reason)

perhaps something like this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "stdafx.h"
#include "math.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std; 

// Variables
string PlayerName="Name1";
int PlayerScore=200;

int main()
{
	ofstream HighScoreFile;
	HighScoreFile.open("highscores.txt");
	HighScoreFile.close();

return 0;
}


I'm not sure what the best way of doing this would be.

Thank you =)
Last edited on
You could comfortably do that with the insertion operators, as if with std::cout.

1
2
HighScoreFile.seekp(0,std::ios::end); //to ensure the put pointer is at the end
HighScoreFile<<"\t\t\t"<<PlayerName<<", "<<PlayerScore;


Aceix.
I've just noticed it keeps overwriting what is already there, it doesn't seem to add to the end of the file each time i run the program... hmm...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "stdafx.h"
#include "math.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std; 

// Variables
string PlayerName="Name1";
int PlayerScore=200;

int main()
{
	ofstream HighScoreFile;
	HighScoreFile.open("highscores.txt");
	HighScoreFile << "\t\t\t" << PlayerName << ", " << PlayerScore << "\n";
	HighScoreFile.close();

	HighScoreFile.seekp(0,std::ios::end); //to ensure the put pointer is at the end
	HighScoreFile<<"\t\t\t"<<PlayerName<<", "<<PlayerScore;

return 0;
}
Last edited on
Correct you got the opening of a file down now you just need to do the actual writing to the file.

First let me clarify, you want this format for your text file correct?

<tab><tab><tab><name>, <score>
<tab><tab><tab><name>, <score>
....
....


If so this is how you would go about accomplishing this. First let's go over opening up a text file and writing to it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
    std::ofstream highScoreFile("highscores.txt");
    
    // Always check to see if the file is open and for errors.
    if (highScoreFile.is_open())
    {
        // If it is open we can do our writing to the file.
        // Here is a example of this.
        highScoreFile << "I am writing to the file!";
    }
    else
    {
        // If the file isn't open something went wrong. Point that out.
        std::cout << "Something went wrong with opening the file!";
    }

    // After you are done with the file always close it.
    highScoreFile.close();
}
    


It is quite easy to write to a file. It is just like writing to the console with std::cout.

Though a important thing to note is that when you use the default ofstream constructor (Like I did above) it is in truncate mode which means it will discard anything in the file already and start over. This is why everything is being deleted.

In order for that not to happen open you file like this.

std::ofstream HighScoreFile("highscores.txt", std::ofstream::out | std::ofstream::app);

or with

open("highscores.txt", std::ofstream::out | std::ofstream::app);

std::ofstream::out means you want to output to the file (Write to it) and std::ofstream::app means you want to append to the file (don't overwrite everything).

Here is some more about the different flags http://www.cplusplus.com/reference/fstream/ofstream/ofstream/

HighScoreFile.open(
Now next up we need to know how to get the formatting right on your text file. As mentioned before you want <tab><tab><tab><name>, <score> for the format I believe.

All you will need to do is write them to the file in that order. Here is some pointers for how to write tabs and newlines (Creates a new line) if you didn't know already.

<tab> = "\t"
<newline> = "\n"

So your format would be like this. playerName = the variable which holds the name, playerNumber is the variable which holds that players number.
highScoreFile << "\t\t\t" << playerName << ", " << playerNumber << "\n";

Hopefully that helps a bit. Let me know if you have any specific questions or if anything is confusing.
Last edited on
What about opening it this way: HighScoreFile.open("highscores.txt",ios::app|ios::ate);

Aceix.
Thank you both for you help, it's been really useful =)

What I have ended up with is :-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "stdafx.h"
#include "math.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std; 

// Variables
string PlayerName="Name1";
int PlayerScore=200;

// Functions
void SaveScore()
{
	ofstream HighScoreFile;
	HighScoreFile.open("highscores.txt",ios::app|ios::ate);
	HighScoreFile << "\t\t\t" << PlayerName << ", " << PlayerScore << "\n";
	HighScoreFile.close();

	HighScoreFile.seekp(0,std::ios::end); //to ensure the put pointer is at the end
	HighScoreFile<<"\t\t\t"<<PlayerName<<", "<<PlayerScore;
}

int main()
{
	SaveScore();

return 0;
}


However with the 'using namespace std; ' does it need the std:: parts? I'm not entirely sure what they mean.
Last edited on
OP wrote:
However with the 'using namespace std; ' does it need the std:: parts? I'm not entirely sure what they mean.


No. The std is a namespace for the standard C++ library. Doing something like std::xxx means, use xxx in std. So using std doesn't need std::xxx anymore, just xxx.

Aceix.
Last edited on
Hmm, when I remove the 'std::' it only overwrites what is in the text file again, not adding to the end of it... Sorry but I'm still a little confused.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "stdafx.h"
#include "math.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std; 

// Variables
string PlayerName="Name1";
int PlayerScore=200;

// Functions
void SaveScore()
{
	ofstream HighScoreFile;
	HighScoreFile.open("highscores.txt",ios::app|ios::ate);
	HighScoreFile << "\t\t\t" << PlayerName << ", " << PlayerScore << "\n";
	HighScoreFile.close();

	HighScoreFile.seekp(0,ios::end); //to ensure the put pointer is at the end
	HighScoreFile<<"\t\t\t"<<PlayerName<<", "<<PlayerScore;
}

int main()
{
	SaveScore();

return 0;
}
Last edited on
it only overwrites what is in the text file

That's because the default mode (2nd parameter to open) is truncate.

Try this to append to the file as Aceix suggested:
 
  HighScoreFile.open ("highscores.txt", ios::app);


Lines 20 and 21 won't work because the file is closed at line 18.


Last edited on
Ok I think I have stumbled into waters a little too deep for me at the moment. For the sake of my learning I went with: -

1
2
3
4
5
6
7
void SaveScore()
{
	ofstream HighScoreFile;
	HighScoreFile.open("highscores.txt",ios::app);
	HighScoreFile<<"\t\t\t"<<PlayerName<<", "<<PlayerScore<<"\n";
	HighScoreFile.close();
}


Probably not the cleanest way of doing it but I'll revisit this another time.

Thank you very much for your help =)
Last edited on
Not the most efficient, but it works.

Keep in mind that the open of the file can fail.
AbstractionAnon wrote:
Keep in mind that the open of the file can fail.

This is definitely something that you should always check for. The open can fail from something as little as the text file not being in the right spot to even more rare causes. So you should always be checking to see that it opened correctly before continuing.

In you example it would look something like this (Heavy commenting).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void SaveScore()
{
	ofstream HighScoreFile;
	HighScoreFile.open("highscores.txt",ios::app);

	// This is how you check to make sure there was no errors while 
	// opening the file. Always do this check and then just put the
	// operation you wish to do inside the if brackets.
	if (HighScoreFile.is_open())
	{
		HighScoreFile<<"\t\t\t"<<PlayerName<<", "<<PlayerScore<<"\n";
		HighScoreFile.close();
	}
	else // What to do if we do fail to open the file
	{
		// In here you can do whatever you want to do when the file
		// fails to open. It might just be as simple as printing something 
		// simple to the console like this.
		cout << "Failed to open the file!";

		// Or you could go into much deeper error handling like trying to 
		// fix the problem (Find the correct path to the file, or other things).
	}		
}


Usually it is just a simple if statement like that to check if the open worked and to handle any errors (You can also get into exceptions but that is a bit more advanced).
Topic archived. No new replies allowed.