1

I want to delete a line of my text file without replacing it with " ". Just as a side note: my file has newlines. So I have more than one line (like a table)

void Data::delete_line(const string& idNr) {
    ifstream list;
    string readFile, id;
    list.open("list.txt", ios::app);

    if (list.is_open()) {
        while (getline(list, readFile)) {
            int pos = readFile.find(';');
            id = readFile.substr(0, pos);
            if (idNr == id) {
                //deleting the line here
            }
        }
    }

}

I found this question but it does not solve my problem:

Shalomi90
  • 736
  • 4
  • 9
  • 33
  • 4
    You can't delete a line from an `ifstream`, at least you'll need to use a `std::fstream` which is capable to write back to the opened file. – πάντα ῥεῖ Nov 19 '18 at 19:52
  • 1
    Think of a file like an array. You can't remove the middle element. You have to move everything forward. – NathanOliver Nov 19 '18 at 19:53
  • Everything after that has to move up, so there is no advantage to not creating a new file – stark Nov 19 '18 at 19:53
  • @NathanOliver Thats what I want :) IThe other lines have to move after deleting one line – Shalomi90 Nov 19 '18 at 19:53
  • Then you will need a loop to copy everything after the removed line towards the beginning of the file by the size of the removed line. – Galik Nov 19 '18 at 19:56
  • 1
    If you need a database, use a database, not a plain file. – n. m. could be an AI Nov 19 '18 at 19:58
  • I have to use a plain file :) @n.m. – Shalomi90 Nov 19 '18 at 19:59
  • @IT_Geek_Oz As mentioned 1st of all you'll need a `std::fstream` to be able to manipulate the file inline without creating a new `std::ofstream`. Also to delete a particular line there you have to manipulate the `std::fstream` to rewrite everything that comes after the line's position. That's just complicated and error prone vs reading the whole file into a `std::vector` representing all the lines, manipulate the vector, and write back the result in whole. – πάντα ῥεῖ Nov 19 '18 at 20:06
  • @πάντα ῥεῖ, What if the file is 50 gigabytes? – Peter Ruderman Nov 19 '18 at 20:06
  • @PeterRuderman You'll going to read it line by line, and putting output to a different `std::ostream` filtered. That requires another `std::ofstream` of course. – πάντα ῥεῖ Nov 19 '18 at 20:10

2 Answers2

1

Maybe you can just create a new file and put your data into the new file. Like this:

void Data::delete_line(const string& idNr) {
ifstream list;
ofstream outFile("newList.txt");
string readFile, id;

list.open("list.txt", ios::app);

if (list.is_open()) {
    while (getline(list, readFile)) {
        int pos = readFile.find(';');
        id = readFile.substr(0, pos);
        if (idNr != id) {
            outFile << readFile;
        }
    }
}
list.close();
outFile.close();

remove("list.txt");
rename("newList.txt", "list.txt");
}

At the end you just remove your old file and rename the new file with the name of the old file. I hope this will solve your problem.

gmz
  • 64
  • 6
0

Without creating a new file, Its impossible to remove a line in the middle of file. Unless you replace it in place.

So in this state, just you have to use of bellow method :

std::ostream::seekp

Notice this example :

// position in output stream
#include <fstream>      // std::ofstream

int main () {

  std::ofstream outfile;
  outfile.open ("test.txt");

  outfile.write ("This is an apple",16);
  long pos = outfile.tellp();
  outfile.seekp (pos-7);
  outfile.write (" sam",4);

  outfile.close();

  return 0;
}

In this example, tellp is used to get the position in the stream after the writing operation. The pointer is then moved back 7 characters to modify the file at that position, so the final content of the file is:

This is a sample