JosiP
JosiP

Reputation: 3079

reading and writing to the same file c++

I have small app which at begin will read text file (with serialized objects) in which im storing some obejcts (im doing it by overloading << and >> operators). This text file has to be updated each time new object is created:

fstream m_haystackMapFile;
m_haystackMapfile.open(haystackMapFile,  std::ios::binary | std::ios::in | std::ios::out);

first i do read:

WHaystackFile f;
m_haystackMapfile.seekg(0, std::ios::beg);

std::copy(std::istream_iterator<WHaystackFile>(m_haystackMapfile), std::istream_iterator<WHaystackFile>(), std::back_inserter(m_haystackFiles));

std::cout << "reading input file, no of files: " << m_haystackFiles.size() << std::endl;
for(std::vector<WHaystackFile>::iterator it = m_haystackFiles.begin(); it != m_haystackFiles.end(); ++it){
    f = *it;
    std::cout << "key: " << f.getKey() << " cookie: " << f.getCookie()  << " path: " << f.getPath()  << " size: " << f.getSize()<< std::endl;
}

then after creating new object I do write:

void WhaystackMap::addEntry(WHaystackFile &f){
    std::cout << "adding entry to index file" << std::endl;
    m_haystackMapfile.seekp(std::ios::end);
    m_haystackMapfile << f;
    std::cout << f;

}

unfortunatelly file in which I want to write is never updated and it always has size 0. Maybe im messing up something, but after googling i can't find answer how to using fstream I can read and write to same file...

any help is welcomed :)

regards J.

Upvotes: 1

Views: 2756

Answers (2)

rici
rici

Reputation: 241721

It's very important to check success of I/O operations. For example, if seekp is unable to seek to the desired position, it will set the failbit, and then all subsequent writes will fail. Or, as @Christophe points out, if you read the file to the end, you will cause the eofbit to be set. Unless that bit is cleared, the next I/O operation (even seekp) will fail.

Even if the eofbit had been reset, the seek probably would fail because the call should have been m_haystackMapfile.seekp(0, std::ios::end);.

Upvotes: 4

Christophe
Christophe

Reputation: 73376

The problem is the wrong usage of seekp():

  • you use it with one single parameter ios::end in m_haystackMapfile.seekp(std::ios::end)
  • but single parameter only works for absolute positionning. So ios::end is converted into an integer and will locate you at an unexpected place (on my implementation it's 2).
  • you have to use m_haystackMapfile.seekp(0, std::ios::end) instead

There is another problem: the istream_iterator<>() that you use in your std::copy() will read the stream until it reaches its end. So the failbit and eofbit will be set.

Connsequently, no stream operation will succed until you clear the flags: m_haystackMapfile.clear();

Upvotes: 3

Related Questions