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::vector
s and std::string
s 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::getline
which 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_line
until you've reached the line you want to remove. If you want to remove line 2, callskip_line
1 time. If you instead want to remove line 3, callskip_line
2 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_line
one 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
char
at a time from thereadpos
position and write thatchar
to thewritepos
position. 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_size
andstd::filesystem::resize_file
to fix this. Remember that you storedlenght_of_line_to_be_removed
above. If you use a version of C that does not havestd::filesystem
, you need to use some platform specific function. Posix systems have thetruncate
function 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");
}