Can't read and write the same file?

Hi, I'm trying to make a save game system for my text adventures. I have no experience reading and writing files, so I wrote a test program to teach myself:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;

int main()
{
	ofstream fout("save.txt");
	ifstream fin("save.txt");
	int x;
	fin >> x;
	fout << x + 1 << endl;
	
	return 0;
}


When I run the program, save.txt contains the number 3 and a newline. So the program should read in a 3, then change the contents of save.txt to 4. But instead it prints the leftover memory that was dumped into x when it was declared (2130567169). How do I properly read in from and write to the same file?
why are you trying to take info from a file and replace it?
Thanks for the link! But how do I overwrite the file with the output? I want to read in, then completely overwrite. Will truncating do that?

EDIT: I tried truncating, but it wiped the file before I could read its contents. To clarify, I need to open it, read its contents, THEN wipe it, then write to it.


EDIT: It all works perfectly now. Thanks for your help! This opens up so many new opportunities for me. I'm so excited!

@ui uiho: I plan to read in the save data, allowing the player to load their save game. Then I plan to overwrite the save file with their new save data when they're done playing.
Last edited on
ok, i also noticed you forgot to close the files in the first program. you need to do
filename.close();
or the file will be left open in the ram. this is not a great thing. remember when people tell you to always close files before closing them? this is the same kind of thing but instead of just losing info you are also losing space in your ram. the ram resets itself when you restart your computer so you do not actually have any damage. but if you are running like a gigabit worth of info in files and forget to close them you will almost always require a computer restart after the program runs.
The fstream family closes the file when the destructor is invoked. There is no need to explicitly close them.
Last edited on

EDIT: It all works perfectly now. Thanks for your help! This opens up so many new opportunities for me. I'm so excited!


I was trying to help you more last night but couldn't get it working myself. Could post a template or something (nothing fancy, maybe just read a number and print back the number plus one.)?

The fstream family closes the file when the destructor is invoked. There is no need to explicitly close them.


Will all of the data be written to the file? Maybe some Java confusion here.
Yes, it flushes and closes.
fstream fileacesss("save.txt", ios::in | ios::out | ios::app);

You don't need to have 2 objects. This object reads and writes altogether.
Thanks LB.

At this point I have the same problem that NetHacker had, this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>
using namespace std;

int main(){

	fstream file("input.txt", ios::in | ios::out | ios::app);
	int data;

	file >> data;
	file << data +1;
	
	file.close();


	return 0;
}


Does not write data + 1 to the file. (though it would cout the correct value of data).
I can't test right now, but can you post the before and after of the file contents?
The file is 3 before and after.

While I am sure that this isn't the issue, the file is open in VS. When I write to a ifstream who's file is open in VS, VS will pop up "The file changed, do you want to reload". This doesn't happen with the code I posted.
Does it happen if you edit the file in notepad? I thought that feature only worked for source and header files.

I do wonder, though, why you are using ios::app? This means append, as in don't overwrite the existing data.
Does it happen if you edit the file in notepad?

Indeed.

why you are using ios::app?

Just from TheDestroyer's post. Without it I still have issues.

I think it has something to to with the write position. I tried all kinds of things last night (check to make sure the file is good, set the write position back to 0, etc). As soon as I extract from the file I can't write back into it.

Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <fstream>
using namespace std;

int main(){

	fstream file("input.txt", ios::in | ios::out | ios::app);
	int data;

	file >> data;
        file.clear() ;
	file << data +1;
	
	file.close();


	return 0;
}


After a write, you generally need to seekg() before reading again. After a read, you generally need to seekp() before writing again.

Edit: JLBorges is right about the eof flag, but the above is still true. See: http://www.icce.rug.nl/documents/cplusplus/cplusplus06.html#FSTREAM

Last edited on
> I think it has something to to with the write position.

It has to do with the file containing a single integer with no new line at the end.
1
2
3
	file >> data;
	file.clear() ; // *** clear the eof flag
	file << data +1;

Things seems to be working correctly now, thanks for the help.

The new mystery is: why wasn't this working last night!!!
> After a read, you generally need to seekp() before writing again.

Not if the stream is opened with std::ios_base::app - seekp() has no effect (fails) on such a stream.

Meaning of std::ios_base::app is 'seek to end before each write'


You would think so.

VC++ and g++ differ here. g++ doesn't require the seek, VC++ does. Perhaps VC++ is nonconforming in this respect.

1
2
3
	file >> data;
        file.clear() ;
	file << data +1;


This doesn't work for VC++ (when opened with ios::in | ios::out | ios::app) if there's a space after the number in the file, unless you also throw in a seekp() between the read and write. It does work when the number is followed immediately by the eof indicator.
Topic archived. No new replies allowed.