Thread: how to delete entry in a txt file?

  1. #1
    Registered User
    Join Date
    Nov 2002
    Posts
    117

    how to delete entry in a txt file?

    if there is a *.txt file with the following entries:

    hello
    hi
    all

    how to delete the line "hi" so that the file will have the following pattern?

    hello
    all

    thank you for helping

  2. #2
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    Could also do this,

    Code:
    #include <iostream>
    #include <fstream>
    #include <stdlib.h>
    #include <string>
    
    int main()
    {
        ifstream file("C:/temp/test.txt");
    
        if ( file.good() )
        {
           file.seekg(0, ios::end);
           int size = file.tellg();
           file.seekg(0, ios::beg);
           char *data = new char[size];
    
           file.read(data, size);
    
           string token(data);
           int loc = token.find("hi",0);
    
           if (loc != string::npos)
           {
              token.erase(loc,3);
           }
    
           fstream newfile("C:/temp/test.txt", ios::out | ios::trunc);
           if ( newfile.good() )
           {
               newfile.write( token.c_str(), token.length() );
               newfile.flush();
           }
           else
           {
              cout << "Error with newfile" << endl;
           }
    
           newfile.close();
        }
        file.close();
        system("PAUSE");
        return 0;
    }

  3. #3
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    hmm... I read somewhere that you get a more accurate file size if you open the stream in binary mode.

    Code:
    ifstream file("C:/temp/test.txt",  ios::bin);

  4. #4
    Registered User moonwalker's Avatar
    Join Date
    Jul 2002
    Posts
    282
    Originally posted by Salem
    You copy to a temp file all the lines you want to keep.
    You then delete the original, and rename the temp file
    wouldn't that be slow if the file is considerably big?
    How would you do it to make it faster ?

    Mmm, I wonder who can spot the non-obvious 'bug' in laasunde's answer.
    oh.. you mean the "/" to "\" ? I don't know if that would make a difference though... hmm
    Last edited by moonwalker; 07-16-2003 at 08:20 AM.

  5. #5
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361
    Originally posted by Salem
    Mmm, I wonder who can spot the non-obvious 'bug' in laasunde's answer.
    I immediately see two things wrong: He's erasing 3 character instead of 2 ("hi")
    He's putting all the data into an std::string, the any occourance of a '\0' character in the file is going to screw everything up.
    Do I get a cookie?

  6. #6
    Seeking motivation... endo's Avatar
    Join Date
    May 2002
    Posts
    537
    Code:
    char *data = new char[size];
    is it just me or does this need deleting?
    Couldn't think of anything interesting, cool or funny - sorry.

  7. #7
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Our good friend laasunde has a couple of problems:
    1) As endo pointed out, `data` isn't delete'd
    2) He assigns `data` to std::string token without first appending a NULL byte to data (which should be 1 byte larger than allocated for just this reason)
    3) It is just not "general purpose" enough to work well. As someone else said, if you have a huge file (like perhaps a gig) your program is down the crapper trying to read the entire file into a string.
    4) He is searching for the string "hi" in its first occurrence regardless of whether it might be part of another string or not the only thing on the line.

    I feel the only good solution is to just read from source and write to a temp file everything except what you want to keep (in Jasonymk's example it would be "hi\n"). Then delete the source and rename the temp.

  8. #8
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    My-oh-my... thats alot of bugs.

    Have done a bit of editing and came up with this version :

    Code:
    #include <iostream>
    #include <fstream>
    #include <stdlib.h>
    #include <string>
    #include <stdio.h>
    
    int main()
    {
        ifstream file("C:/temp/test.txt", ios::in);
    
        if ( file.good() )
        {
         file.seekg(0, ios::end);
         int size = file.tellg();
         file.seekg(0, ios::beg);
         char *data = new char[size + 1];
         file.read(data, size);
         file.close();
    
         *(data + size + 1) = '\0';
         string token(data);
         delete[] data;
    
         int loc = token.find("hi",0);
    
         if (loc != string::npos)
         {
            token.erase(loc,3);
         }
    
         fstream newfile("C:/temp/test1.txt", ios::out);
         if ( newfile.good() )
         {
              newfile.write( token.c_str(), token.length() );
              newfile.flush();
         }
         else
             cout << "Error with newfile" << endl;
    
         newfile.close();
    
    
         if ( remove("C:/temp/test.txt") != 0)
            cout << "Error on remove" << endl;
    
         if ( rename("C:/temp/test1.txt", "C:/temp/test.txt") != 0)
             cout << "rename failed" << endl;
        }
    
        file.close();
        system("PAUSE");
        return 0;
    }
    Just like to add that this code is specially made for the above mentioned example.

    I still belive token.erase(loc,3); is correct, you need to remove two char's and a newline - adding up to 3.. right ?

    Using / instead of \\ makes the program more portable I belive since both unix and windows uses that method and only windows uses \\.

    Anymore bugs ?

  9. #9
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Without gettin way too far off track, imagine the case where the three lines are:
    > hillo
    > hi
    > all
    Just searching for "hi" isn't enough. You should be searching for a lone line with only "hi" on it... Still, however, you should make even more radical changes to the code. You should not be reading the entire file then searching through it in memory and deleting what you don't want to keep. This is a big mistake. Again, imagine if the file is a gigabyte in size. Odds are that you don't have a gig of ram available... All you should be doing is reading a bit at a time from the source, checking if it is wanted and if so, writing it to the temp file. That's it...

    Try this:
    Code:
    std::string str;
    while (fin.good()) {
      getline(fin, str);
      if (!fin.good())
        break;
      if (str != unwantedString)
        fout << str << endl;
    }
    remove (source);
    rename (temp, source);

  10. #10
    Registered User
    Join Date
    Nov 2002
    Posts
    117

    thank you for helping...

    hi all,~~~

    may be i should make the question more clearer....
    my txt file is like this:

    data 1 data 2 data 3 data 4
    data 1 data 2 data 3 data 4
    and so on

    say for example, data 3 is the date, my program wish to check the date if it is expired, if it is, delete it, if not, then keep it.

    i have ask about date and time here and i have got the solution.
    what i cant solve is how to delete the whole line when the date is checked?
    Last edited by Jasonymk; 07-16-2003 at 06:58 PM.

  11. #11
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Again Jasonymk, read through the file. Write the records you want to keep into a temp file and discard records you do not want to keep. Then delete the existing file and replace it with the temp file.

    I don't understand what you don't understand about that... If it is still unclear, please explain why.

  12. #12
    Registered User
    Join Date
    Nov 2002
    Posts
    117
    thank you.....i undrstand what you mean....
    only the idea is new to me.....

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The code still uses the deprecated C headers (should be cstdlib etc.) and never qualifies std:: in any way.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    LuckY : I understand what you mean by not loading the whole thing into memory but when I wrote the example it was a 14 byte file so it's wasnt really an issue, for me anyway.

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    As an alternative: open the file, open a new file. Read one line and if you don't want to filter it out, write it to the other file. Continue until there are no more lines.

    That way you only need enough space to store one line, not the entire file.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie homework help
    By fossage in forum C Programming
    Replies: 3
    Last Post: 04-30-2009, 04:27 PM
  2. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  3. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  4. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  5. Problem need help
    By Srpurdy in forum C++ Programming
    Replies: 1
    Last Post: 07-24-2002, 12:45 PM