Search code examples
c++filetextfstreamofstream

Overwrite an existing text file c++


This is how my Save As works - it is copying the current file's lines until it reaches the first figure and then I use my print methods to print the figure's info and then close the tag.

std::ofstream newFile(filePath1_fixed, std::ios::app);
std::fstream openedFile(filePath);
std::string line1;
while (std::getline(openedFile, line1)) {
    if (line1.find("<rect") != std::string::npos
        || line1.find("<circle") != std::string::npos
        || line1.find("<line") != std::string::npos)
        break;
    newFile << line1 << std::endl;
}
figc.printToFile(newFile);
newFile << "</svg>\n";

My question is how to save the changes to the current file? I tried something like this:

std::ifstream openedFile(filePath);
std::ofstream newFile(filePath, std::ios::app);
std::string line1;
std::string info_beg[100];
int t = 0;
while (std::getline(openedFile, line1)) {
    std::cout << "HELLYEAH";
    if (line1.find("<rect") != std::string::npos
        || line1.find("<circle") != std::string::npos
        || line1.find("<line") != std::string::npos)
        break;
    info_beg[t++] = line1;
}
for (int i = 0; i < t; i++)
    newFile << info_beg[i] << std::endl;
figc.printToFile(newFile);
newFile << "</svg>\n";

This is the nearest I've gone. I get this:

  <?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="12cm" height="4cm" viewBox="0 0 1200 400"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  <desc>Example rect01 - rectangle with sharp corners</desc>

  <!-- Show outline of canvas using 'rect' element -->
  <rect x="1" y="1" width="1198" height="398"
        fill="none" stroke="blue" stroke-width="2" />

  <line x1="20" y1="100" x2="100" y2="20"
        stroke="red" stroke-width="2" />

  <rect x="20" y="30" width="40" height="50"
        fill="red" stroke="red" stroke-width="1" />

  <rect x="10" y="20" width="30" height="40"
        fill="red" stroke="blue" stroke-width="1" />

  <line x1="100" y1="200" x2="300" y2="400"
        stroke="red" stroke-width="2" />

  <circle cx="10" cy="20" r="30"
        fill="red" stroke="blue" stroke-width="2" />

</svg>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="12cm" height="4cm" viewBox="0 0 1200 400"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  <desc>Example rect01 - rectangle with sharp corners</desc>

  <!-- Show outline of canvas using 'rect' element -->
  <rect x="1" y="1" width="1198" height="398"
        fill="none" stroke="blue" stroke-width="2" />

  <line x1="20" y1="100" x2="100" y2="20"
        stroke="red" stroke-width="2" />

  <rect x="20" y="30" width="40" height="50"
        fill="red" stroke="red" stroke-width="1" />

  <rect x="10" y="20" width="30" height="40"
        fill="red" stroke="blue" stroke-width="1" />

  <line x1="100" y1="200" x2="300" y2="400"
        stroke="red" stroke-width="2" />

  <circle cx="10" cy="20" r="30"
        fill="red" stroke="blue" stroke-width="2" />

  <rect x="10" y="20" width="30" height="40"
        fill="red" stroke="blue" stroke-width="2" />

</svg>

So my actual question is how to delete the first or overwrite it or I need a different approach.


Solution

  • Use ios::trunc instead of ios::app

    Using std::ios::app in the constructor for your std::ofstream tells the program to append to the file and not overwrite it. If you want to overwrite it (ie truncate), then using std::ios::trunc will tell the program to overwrite the existing file. ofstream does this by default, so you could just write the initialization as just std::ofstream newFile(filePath);.

    Also, don't try to read the file and write to it at the same time; that won't work. Use ifstream to get the data into the buffer, then use close() to close the file. Then initialize newFile to overwrite the file and write out the buffer.