How to read and write in file with `fstream` simultaneously in c++?

12,798

Solution 1

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;

Solution 2

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
Share:
12,798
Anirban Nag 'tintinmj'
Author by

Anirban Nag 'tintinmj'

If anyone is too kind to endorse me for my skills in Linkedin, thanks. Some wild bookmark(s) Peter Norvig Java IAQs ¡¡¡¡ʎɐp ʇɐǝɹb ɐ ǝʌɐɥ puɐ ʞɔɐq ob 'ʍou ʎɐs oʇ buıɥʇou ˙˙˙˙ɯɯɯɯɯɥ

Updated on June 04, 2022

Comments

  • Anirban Nag 'tintinmj'
    Anirban Nag 'tintinmj' almost 2 years

    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?

    • Nawaz
      Nawaz over 8 years
      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.
    • Jonathan Wakely
      Jonathan Wakely over 8 years
      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.
    • Lightness Races in Orbit
      Lightness Races in Orbit over 8 years
      @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...
    • Jonathan Wakely
      Jonathan Wakely over 8 years
      @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 :)
  • sonus21
    sonus21 over 8 years
    But it should write at the beginning of the file. I tried it's not even writing at the file.
  • eerorika
    eerorika over 8 years
    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?
  • eerorika
    eerorika over 8 years
    Also, why does the output position being at the beginning not cause the beginning of the file to be overwritten?
  • Alexander
    Alexander over 8 years
    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