Sign in to follow this  
ordered_disorder

Need help with reading and writing to the same file

Recommended Posts

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.

Share this post


Link to post
Share on other sites
AAAP    137
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Fruny    1658
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'.

Share this post


Link to post
Share on other sites
AAAP    137
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.

Share this post


Link to post
Share on other sites
Fruny    1658
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.

Share this post


Link to post
Share on other sites
AAAP    137
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Fruny    1658
Quote:
Original post by ordered_disorder
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.


It's common knowledge. [wink]

Windows: \r\n
Unix: \n
MacOS \r (pre-OSX, I believe)

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