Search code examples
c++filec++11ofstream

How do I move back X bytes from the end of a file and edit it? (Using ofstream in c++)


All I want to do is move the 'put' pointer from the end of the file to a point 'X' bytes behind the end of the file.

#include <iostream>
#include <fstream>
using namespace std;
int main(){
    ofstream ofile;
    //Assuming "file.dat" does not exist
    ofile.open("file.dat", ios::binary|ios::app);
    int x = 12;
    ofile.write((char*) &x, sizeof(int));
    ofile.seekp(-4, ios::cur);
    x = 10;
    ofile.write((char*) &x, sizeof(int));
    ofile.close();

    x = 0;
    ifstream ifile("file.dat", ios::binary);
    ifile.read((char*) &x, sizeof(int));
    cout<<x; //This line should display 10
    return 0;
}

However, the output displays 12...

Image of output here...

I read many articles on StackOverflow, which did mention that to 'seek' the 'put' pointer, I must use 'ios::ate', and not 'ios::app'.

But I even tried using the following instead, and I still had no luck...

 ofile.open("file.dat", ios::binary|ios::ate);

Is what I'm doing wrong? Is there another way to move the 'put' pointer back as such?

This is just the simpler version of what was not working in the project I need to make for school...

Any help will be appreciated... Thank you...


Solution

  • When you specify ios::app it means "write everything always to the end, don't care about the put pointer.

    If you always want to start writing at the end, but want to also be able to move around, then you need ios::ate, but if you use just ios::binary|ios::ate then the file will be truncated. You need to add ios::in and it will work.

    This will work when the file exists and will write to the end, overwrite and then read it.

    #include <iostream>
    #include <fstream>
    using namespace std;
    int main(){
        ofstream ofile;
        //Assuming "file.dat" does not exist
        ofile.open("file.dat", ios::binary|ios::in|ios::ate);
        int x = 12;
        ofile.write((char*) &x, sizeof(int));
        ofile.seekp(-4, ios::cur);
        x = 10;
        ofile.write((char*) &x, sizeof(int));
        ofile.close();
    
        x = 0;
        ifstream ifile("file.dat", ios::binary|ios::ate);
        ifile.read((char*) &x, sizeof(int));
        ifile.seekp(-4, ios::cur);
        cout<<x; //This line should display 10
        return 0;
    }