How to write to middle of a file in C++?

16,749

Solution 1

You cannot insert in the middle of the file. You have to copy the old file to a new file and insert whatever you want in the middle during copying to the new file.

Otherwise, if you intend to overwrite data/lines in the existing file, that is possible by using std::ostream::seekp() to identify the position within the file.

Solution 2

You could write to the end and swap lines until it ends up in the right position. Here's what I had to do. Here's the test.txt file before:

12345678
12345678
12345678
12345678
12345678

Here's a sample of my program

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

fstream& goToLine(fstream& file, int line){
    int charInLine = 10;  //number of characters in each line + 2
                          //this file has 8 characters per line

    int pos = (line-1)*charInLine;

    file.seekg(pos);
    file.seekp(pos);

    return file;
}

fstream& swapLines(fstream& file, int firstLine, int secondLine){
    string firstStr, secondStr;

    goToLine(file,firstLine);
    getline(file,firstStr);
    goToLine(file,secondLine);
    getline(file,secondStr);

    goToLine(file,firstLine);
    file.write(secondStr.c_str(),8);    //Make sure there are 8 chars per line
    goToLine(file,secondLine);
    file.write(firstStr.c_str(),8);

    return file;
}

int main(){
    fstream file;
    int numLines = 5; //number of lines in the file

    //open file once to write to the end
    file.open("test.txt",ios::app); 
    if(file.is_open()){
        file<<"someText\n"; //Write your line to the end of the file.
        file.close();
    }

    //open file again without the ios::app flag
    file.open("test.txt"); 
    if(file.is_open()){
        for(int i=numLines+1;i>3;i--){ //Move someText\n to line 3
            swapLines(file,i-1,i);
        }
        file.close();
    }

    return 0;
}

Here's the test.txt file after:

12345678
12345678
someText
12345678
12345678
12345678

I hope this helps!

Solution 3

Based on my basic knowledge of Operating systems, I would say it is not possible. I mean it is not impossible to make an OS that can allow such functionality with current storage technologies, but doing so would always lead to wastage of space in segments.

But I am not aware of any technology that can allow that. Although some cloud-based DataBases do use such kinds of functionally (like inserting content in middle of a file), but they are made specifically for that DBMS software, with very specifically targeted hardware, and they may also have some custom-built kernels to perform such tasks.

Share:
16,749
nburk
Author by

nburk

learning &amp; teaching @ prisma.io https://twitter.com/nikolasburk/status/1093913218676940805

Updated on June 04, 2022

Comments

  • nburk
    nburk almost 2 years

    I think this should be quite simple, but my googling didn't help so far... I need to write to an existing file in C++, but not necessarily at the end of the file.

    I know that when I just want to append text to my file, I can pass the flag ios:app when calling open on my stream object. However, this only let's me write to the very end of the file, but not into its middle.

    I made a short program to illustrate the issue:

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main () {
    
      string path = "../test.csv";
    
      fstream file;
      file.open(path); // ios::in and ios::out by default
    
      const int rows = 100;
      for (int i = 0; i < rows; i++) {
        file << i << "\n";
      }  
    
      string line;
      while (getline(file, line)) {
        cout << "line: " << line << endl; // here I would like to append more text to certain rows
      }
    
    
      file.close();
    
    }
    
  • KriptSkitty
    KriptSkitty almost 9 years
    Just to be complete: You can't insert into the middle of a file, but you can replace, the same number of bytes, by overwriting.
  • Anil
    Anil almost 9 years
    to complete further, refer example code; stackoverflow.com/questions/2393345/…
  • 911
    911 almost 9 years
    basically, you can move the file pointer anywhere using seekp() member function, and start writing. However, any writes before EOF will replace the old data.