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
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
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; }
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);
wouldn't that be slow if the file is considerably big?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
How would you do it to make it faster ?
oh.. you mean the "/" to "\" ? I don't know if that would make a difference though... hmmMmm, I wonder who can spot the non-obvious 'bug' in laasunde's answer.
Last edited by moonwalker; 07-16-2003 at 08:20 AM.
I immediately see two things wrong: He's erasing 3 character instead of 2 ("hi")Originally posted by Salem
Mmm, I wonder who can spot the non-obvious 'bug' in laasunde's answer.
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?
is it just me or does this need deleting?Code:char *data = new char[size];
Couldn't think of anything interesting, cool or funny - sorry.
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.
My-oh-my... thats alot of bugs.
Have done a bit of editing and came up with this version :
Just like to add that this code is specially made for the above mentioned example.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; }
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 ?
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);
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.
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.
thank you.....i undrstand what you mean....
only the idea is new to me.....
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
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.
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