Search code examples
c++fstream

use fstream to read and write in the same time


I am learning how to read and write from file . There is a problem that when I try to write (--something in the file letter for example--) after reading or read after writing in the file using fstream
something wrong is happening. I tried to just write or read and it worked. what is the problem?

the file content is :

abcdefgh
ijklmnopqr
stuvw
xyz

and the code is :

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
fstream ioFile;
    char ch;
    ioFile.open("search.txt", ios::in | ios::out);
    if (!ioFile)
    {
        cout << "problem opening the file";
        goto k270;
    }
    
    while (ioFile>>ch)
    {
        if (ch == 'z')
        {
            ioFile.seekp(((int)ioFile.tellg()));
             ioFile << "x";
            
            
        }
    }


    //cout<<ioFile.rdbuf();
    ioFile.close();
    k270:
    system("pause");
    return 0;
}

Solution

  • Look at this answer: https://stackoverflow.com/a/17567454/11829247 it explains the error you are experiencing.

    Short version: Input and output is buffered and interleaving reads and writes only work if you force buffer updates in between.

    This works for me:

    #include <iostream>
    #include <fstream>
    #include <string>
    
    int main()
    {
        std::fstream ioFile;
        char ch;
        ioFile.open("search.txt", std::ios::in | std::ios::out);
        if (!ioFile)
        {
            std::cout << "problem opening the file";
            return 1;
        }
    
        while (ioFile >> ch)
        {
            if (ch == 'z')
            {
                ioFile.seekp(-1, std::ios_base::cur);
                ioFile << "x";
                ioFile.flush();
            }
        }
    
        ioFile.close();
        return 0;
    }
    

    The difference is that I use ioFile.seekp(-1, std::ios_base::cur); to move one step back from the current position. You could also use ioFile.seekp((int)ioFile.tellg() -1); - note the -1.

    Then after stepping back and overwriting the z, use ioFile.flush(); to force the write to be pushed to file. This also means that the read buffer is updated, without this the read operation just steps back in its buffer and keeps reading the same buffered z.