the professor gave told us to delete a line in a txt file without the help of another file or an array, i tried to replace the line with backspace but it print the BS character instead
void rem()
{
fstream f("test.txt");
f.seekp(3, ios_base::beg);
f.write("\b",sizeof(char));
f.close();
}
1
2
3
4
5
i want to remove 2
1
3
4
5
after searching for few hours i found that everyone use another file or a vector or the try to replay the line with BS like me.
CodePudding user response:
Backspace will not do what you hoped for. A backspace character takes up one char just like any other character. When printed on devices capable of moving the cursor backwards, that's what'll happen. It's just a visual thing and it does not work with files.
Since you are not allowed to use another file or arrays, I'm going to assume that std::vectors and std::strings are also forbidden so I suggest shifting everything down in the file, one char at a time, to overwrite the line to be removed.
You will need a function like
std::getlinewhich is capable of reading a line from a stream into astd::string- but you do not need to store any data so we can call itskip_line. It could look like this:std::istream& skip_line(std::istream& is) { // read until reading fails or a newline is read: for(char ch; is.get(ch) && ch != '\n';); return is; }When you've opened the file, call
skip_lineuntil you've reached the line you want to remove. If you want to remove line 2, callskip_line1 time. If you instead want to remove line 3, callskip_line2 times.The get (
f.tellg()) position in the stream is now where you should start writing when you move everyting in the file back to overwrite the line to be removed. Store this position in a variable calledwritepos.Call
skip_lineone time. The get position is now where you should start reading when moving the contents of the file. Store this position in a variable calledreadpos.Calculate and store the length of the line to be removed:
lenght_of_line_to_be_removed = readpos - writepos.Now, you need to read one
charat a time from thereadposposition and write thatcharto thewriteposposition. It could look like this:f.seekg(readpos); // set the _get_ position where we should read from for(char ch; f.get(ch);) { // loop for as long as you can read a char f.seekp(writepos); // set the _put_ position where you should write to f.put(ch); // ...and write the char writepos = 1; // step both positions forward readpos = 1; // -"- f.seekg(readpos); // set the new _get_ position }When the above is done, everything is "shifted down" in the file - but the size of the file will still be the same as it was before. If you use C 17 or newer, you can use the standard functions
std::filesystem::file_sizeandstd::filesystem::resize_fileto fix this. Remember that you storedlenght_of_line_to_be_removedabove. If you use a version of C that does not havestd::filesystem, you need to use some platform specific function. Posix systems have thetruncatefunction that can be used for this.
CodePudding user response:
Technically, this fits requirements :)
$ sed -n "1,2p" input.txt && sed -n "4,9p" input.txt
Or like they said correctly in the comments:
#include <stdio.h>
int main(int argc, char **argv)
{
return system("sed -n \"1,2p\" input.txt && sed -n \"4,9p\" input.txt");
}
