How to write to middle of a file in C++?
Asked Answered
R

3

11

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();

}
Ryurik answered 4/6, 2015 at 11:37 Comment(4)
You might want to use an indexed file library (like GDBM) or sqlite, or even a full-fledged database (PostgreSQL, MongoDB....)Raynaraynah
Standard way of changing files: read input file, process, write to new output file, when succeeded, overwrite input file with output file. There are "faster" alternatives (like ios::app), but they are not for each situation.Radiation
Hasn't this already been asked here like a million times?Specialism
indeed, f.e. here (though, i understand that it's a rhetorical question)Pericarp
L
16

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.

Lepidote answered 4/6, 2015 at 11:39 Comment(3)
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.Integrate
to complete further, refer example code; #2393845Impressionist
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.Rumen
H
6

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!

Hortensehortensia answered 9/8, 2018 at 7:5 Comment(0)
K
0

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.

Kriskrischer answered 14/1, 2020 at 21:48 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.