10

I have the following code

#include<iostream>
#include<fstream>
#include<string>

using namespace std;

int main(void) {
    fstream ofile;
    ofile.open("test.txt", ios::in | ios::out | ios::app);
    for(string line; getline(ofile, line) ; ) {
        cout << line << endl;
    }
    ofile << "stackexchnange" << endl;
    ofile.close();
    return 0;
}

test.txt contains

hello world!
stackoverflow

Above code outputs

hello world!
stackoverflow

And after running the code stackexchange is not appending at the end of test.txt. How to read and then write in file?

4
  • 9
    I think, you need to ofile.clear(); before writing to the file, because once you exit from the loop, the stream is set to badbit or something, which you need to clear() before further doing any operation. Well, that is my guess, I'm not sure though. Commented Sep 7, 2015 at 10:16
  • 2
    Why you no check I/O? If you tested the stream state after doing ofile << "stackexchnange" << endl; you would find it failed, telling you something went wrong. If you also test the state before you'll find the stream state is not good even before you try to write anything. Commented Sep 7, 2015 at 11:27
  • @JonathanWakely: Nice link, although the writing to std::cerr in the fixed example is not only redundant (stick to the exception, or return 1!) but also missing a terminating semicolon... Commented Sep 7, 2015 at 16:16
  • @LightnessRacesinOrbit, fixed the missing semi-colon, thanks. I didn't bother fixing the redundancy. I agree it could be done better, but I'd rather people check and complain twice than not check at all :) Commented Sep 7, 2015 at 16:43

2 Answers 2

16

Nawaz' comment is correct. Your read loop iterates until the fstream::operator bool (of ofile) returns false. Therefore, after the loop, either failbit or badbit must have been set. failbit is set when loop tries to read for the final time but only EOF is left to read. This is completely OK, but you must reset the error state flag before trying to use the stream again.

// ...
ofile.clear();
ofile << "stackexchnange" << endl;
Sign up to request clarification or add additional context in comments.

Comments

7

fstream has two positions : input and output. In your case they both are set to the beginning of the file when you open it.

So you have 4 methods:

tellp // returns the output position indicator 
seekp // sets the output position indicator 
tellg // returns the input position indicator
seekg // sets the input position indicator 

in your case you can use the following line to set output position to the end of the file

ofile.seekp(0, std::ios_base::end);

PS i missed ios::app flag. mea culpa. comment of @Nawaz gives the right answer: after reading the whole file it is necessary to call

ofile.clear(); //cleanup error and eof flags

4 Comments

But it should write at the beginning of the file. I tried it's not even writing at the file.
But they opened the stream with ios::app mode. So why wouldn't output position seek to the end before a write without doing that explicitly?
Also, why does the output position being at the beginning not cause the beginning of the file to be overwritten?
i missed ios::app flag. mea culpa. comment of @Nawaz gives the right answer: after reading the whole file it is necessary to call ofile.clear(); cleanup error and eof flags

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.