EFTH
EFTH

Reputation: 475

writing after reading using fstream

I am under the impression fstream objects in c++ can be used to both read and write, using the same stream. I have successfully been able to first write to a stream and then read from it. If I however try to write to it again the file is not affected.

Here is a code example that successfully compiles on windows using MinGw:

int main()
{
    std::string path="file.txt";

    std::fstream fs(path.c_str());
    int buffSize=100;
    int bytesRead=0;
    char* buffer=new char[buffSize];

    fs.write("hello", 5);
    fs.seekp(0, std::ios::beg);
    fs.read(buffer, buffSize);
    bytesRead=fs.gcount();
    for(int i=0;i<bytesRead;i++) {std::cout << buffer[i];}
    std::cout << "\n";
    fs.clear();
    fs.seekp(1, std::ios::beg);
    fs.write("E", 1);
    std::cout << "fail: " << fs.fail() << "\n";

    delete[] buffer;
}

The initial content of "file.txt" was only:

AAAAAAA

And the program outputs:

helloAA
fail: 0

Looking at the file in a text editor after running the program shows that the final content is:

helloAA

The final writing of the "E" has not taken effect, why is this and how do I fix it?

EDIT:

I tried using fs.clear() before writing again as user 0x499602D2 suggested. Also added a line printing out whether the failbit or badbit has been set or not and updated the program output. The final file content stays the same however, the problem remains.

Upvotes: 2

Views: 4228

Answers (4)

NewLearner
NewLearner

Reputation: 11

once you read a file using fstream, tellg < read pointer > and tellp < write pointer > points to -1. to be able to write again using fstream, just call fstream.clear() and it will reset read and write pointer to where it was before reading.

none of the solution posted above work but fstream.clear() works.

Upvotes: 0

Awais Rafique
Awais Rafique

Reputation: 486

string data="";
string Newdata="New Data";
std::fstream output_file(fileName,  ios::in| ios::out);
output_file >> data; //read Data

 output_file.seekg( 0, ios::beg );//set point to zero
 output_file<<Newdata<<"\n"; //write new Data
 output_file.close();

Upvotes: 0

NetVipeC
NetVipeC

Reputation: 4432

This work in GCC 4.9.0 and VS2013.

Notes:

  • seekg is for move the read pointer
  • seekp is for move the write pointer

In the sample code in line fs.seekp(0, std::ios::beg); need to be seekg. There is no problem because the read pointer has not been move (there is no read until there).

Code:

#include <algorithm>
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char* argv[]) {
  std::string path = "H:\\save.txt";

  int buffSize = 100;
  int bytesRead = 0;
  char* buffer = new char[buffSize];

  std::fstream fs(path.c_str());
  fs.write("hello", 5);
  fs.flush();                        // flushing to disk file
  fs.seekg(0, std::ios_base::beg);   // moving the read pointer
  fs.read(buffer, buffSize);
  bytesRead = fs.gcount();
  for (int i = 0; i < bytesRead; i++) {
    std::cout << buffer[i];
  }
  std::cout << "\n";
  fs.clear();
  fs.seekp(1, std::ios::beg);
  fs.write("E", 1);
  fs.flush();                      // flushing to disk file
  std::cout << "fail: " << fs.fail() << "\n";

  delete[] buffer;

  return 0;
}

Upvotes: 1

E. Moffat
E. Moffat

Reputation: 3288

(more verbose answer from what I posted in comments on the question)

You need to call flush() on output stream objects (derived from ostream) in order for the data to actually be written on the output stream. More information on flush() is available on this c++ reference page.

Upvotes: 1

Related Questions