Need help with reading and writing to the same file

Started by
10 comments, last by ordered_disorder 18 years, 4 months ago
Hi I have two questions regarding fstream for c++. 1) How do I read and than write to the same file using fstream? Whenever I open a file with the fstream constructor and supply the ios flags ios::in, and ios::out, no changes to a file I'm writing to will be saved if I use an input function. To further illustrate what I mean here is some code.

test.txt = 
1
2
3

void main()
{
fstream fio("test.txt", ios::in | ios::out);
cout << (char)fio.get() << endl; // output will be 1
fio << "work damn it!" << endl; // nothing will be saved to the file :(
fio.close();
}

2) I have noticed when using the seekg(pos, seek_dir) function, that there are hidden new line characters in text files, let me illustrate I mean with some source code.

test.txt = 
1
2
3

void main()
{
fstream fio("test.txt", ios::in | ios::out);
fio.seekg(1, ios::beg);
cout << (char)fio.get(); // should be new line , and it is
fio.seekg(2, ios::beg);
cout << (char)fio.get(); // should be "2", but its a new line character, WTF?!?
fio.close()
}

If anybody can add clarity to what is going on, I'd be extremely grateful, thank you for any help.
Advertisement
I'm pretty sure theres another flag for appending to files, i remember it vaguely from an example of that class that i saw a while ago... let me see if i can dig it up for you.

EDIT:

here, some of the other flags are

ios::app -- Append to the file
ios::ate -- Set the current position to the end
ios::trunc -- Delete everything in the file

EDIT:

also, does the seekg member of ios seek through lines, or characters? my guess would be characters, in which case the second character of the first line would be a new line char. X_X
|aaap.penopticon.com| My website, including game projects. Collaboration/comments are welcome, please visit :)
Hi AAAP, ios::app just sets the file output stream so everything is "appened" to the end of the file, and seekg(x, ios::beg) searches x bytes from the beginning of the file, which mean the start of the file starts with 0 not with 1, so in my example, seekg(1, ios::beg) should be a new line character, and seekg(2, ios::beg) should be the number 2, but it's another new line character.
what did the 3rd and 4th character return as?
|aaap.penopticon.com| My website, including game projects. Collaboration/comments are welcome, please visit :)
the third and fourth is "2", and "\n" respectively. The fifth will be another "\n" , sigh...
If you open a file in text mode, you should not expect to be able to pass absolute "byte" offsets to seekg(). This only works in binary mode. In text mode, the only values that have meaning to seekg() are those returned by tellg().

No, binary mode doesn't mean that the data (numbers) are written in binary, it just disables newline translation on platforms that do it.

In practice, you have to remember that, under Windows, a newline is represented, in text mode, by two characters: \r\n. Your first seekg pointed at the beginning of the pair, which is then translated (text mode!) to a single \n. The second seekg pointed at the second character of the pair, a \n, which is passed on unmodified.


Now, regarding your read/write problem, you've got to flush the stream when switching it between read 'state' and write 'state'.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
ok, don't despair, this is good, i think.

0 = "1"
1 = "\"
2 = "n"
3 = "2"

the carriage return could be 2 bytes in length, and getting it with that would show the first byte then the second byte? does that make sense? I'd have to try this myself to be real clear on it. personally, i never even use the ios class.

ok, i was wrong but i was on the right track :P i guess the guy above got it.
|aaap.penopticon.com| My website, including game projects. Collaboration/comments are welcome, please visit :)
Quote:personally, i never even use the ios class.


The C file IO functions work in the same way.

All of this is explicitely spelled out in their documentation.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
then it's likely I've never ran into this type of problem, or solved it with the incorrect assumption I posted above o_O
|aaap.penopticon.com| My website, including game projects. Collaboration/comments are welcome, please visit :)
Quote:Original post by Fruny
If you open a file in text mode, you should not expect to be able to pass absolute "byte" offsets to seekg(). This only works in binary mode. In text mode, the only values that have meaning to seekg() are those returned by tellg().

No, binary mode doesn't mean that the data (numbers) are written in binary, it just disables newline translation on platforms that do it.

In practice, you have to remember that, under Windows, a newline is represented, in text mode, by two characters: \r\n. Your first seekg pointed at the beginning of the pair, which is then translated (text mode!) to a single \n. The second seekg pointed at the second character of the pair, a \n, which is passed on unmodified.


Now, regarding your read/write problem, you've got to flush the stream when switching it between read 'state' and write 'state'.


That was exactly what I wanted to know. Thank you Fruny. How did you figure that out about the windows \r\n, I know that's how windows does newlines in Win32API Windows, but I wasn't even thinking about disk files, thanks again for the perfectly accurate information.

This topic is closed to new replies.

Advertisement