4

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.

drescherjm
  • 10,365
  • 5
  • 44
  • 64
colos_enough
  • 164
  • 1
  • 1
  • 9

1 Answers1

18

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.

Tony Val
  • 362
  • 2
  • 5
  • OP needs more than this, due to taking the to-write data from the same file at the same time. – Lightness Races in Orbit May 03 '17 at 17:46
  • Thank you, this helped. I managed to do it, just had to close the file from which I fill the buffer and then declare the ofstream. – colos_enough May 03 '17 at 17:56
  • 1
    As far as I understand, the default ofstream behaviour is to use std::ios::out which is not quite the same as trunc. out does not remove the original contents, but will start overwriting from the beginning. So one could end up in the situation of having a file containing new and old data, if the new stream is shorter than the old. – mark sabido Apr 07 '22 at 09:33