How to clear std::ofstream file buffer? - c++

I am making a console text editor that continuously saves its content to a text file as text is being written to the editor.
FileEditor editor("C://temp/test.txt");
while (true) {
if (_kbhit()) {
editor.keypress(_getche());
system("cls");
std::cout << editor.content();
editor.save();
}
}
In order to directly save the written content to the text file without having to close() and reopen() the file everytime, I flush the ofstream file buffer directly after inserting text into it.
class FileEditor {
private:
std::ofstream _file;
std::string _content;
public:
// ...
void save() {
_file << _content << std::flush;
}
// ...
};
The problem is when I write multiple characters into the console, for example the string abcd, it will write a to the file, then aab, adding ab to the current buffer content, then aababc, and so on.
Therefore, I wish to clear the ofstream file buffer to replace its contents instead of continuously adding new text to the buffer. Is there a method for clearing the file buffer? Is there a better way of doing what I'm trying to achieve?
I tried finding a method for clearing the buffer and I tried searching online for anyone who might've had the same problem as me, but to no avail.

The problem is when I write multiple characters into the console, for example the string abcd, it will write a to the file, then aab, adding ab to the current buffer content, then aababc, and so on.
Your problem has nothing to do with the file buffer. You are not clearing the editor buffer after writing it to the file, so you are writing the same characters to the file over and over.
The user types a, so your editor buffer is a, and you write a to the file.
Then, the user types b, so your editor buffer is now ab, and you write ab to the file.
Then, the user types c, so your editor buffer is now abc, and you write abc to the file.
Then, the user types d, so your editor buffer is now abcd, and you write abcd to the file.
And so on.
You need to write only the new characters that have entered the editor buffer since the last write to the file. For instance, maintain an index into the editor buffer where the last file write left off, and then have the next file write pick up from that index and advance it for the next file write, etc.
Therefore, I wish to clear the ofstream file buffer to replace its contents instead of continuously adding new text to the buffer. Is there a method for clearing the file buffer? Is there a better way of doing what I'm trying to achieve?
The only way to do this with ofstream is to close the re-open the file stream so that the current file content can be truncated. Otherwise, you will have to resort to using platform-specific APIs to truncate the file without closing it first.

Related

Deleting a specific line in a txt file using istream/ofstream in c++

Here is the code I'm having a trouble with, I have a .txt file that contains a list of users and their passwords using this format: user;password.
I need to search for a user in the file and then delete the line which contains this user.
void deleteauser()
{
string user;
cout<<"Which user do you wish to delete?";
cin>>user;
string line;
string delimiter=";";
string token,token1;
ifstream infile;
infile.open("users.txt",ios::in);
while (getline(infile,line,'\n'))
{
token = line.substr(0, line.find(delimiter));
token1=line.substr(token.length(), line.find('\n'));
if(token==user)
{
//here i need to delete the line of the user that has been found
}
}
infile.close();
}
Read the input file, line by line, writing to a temporary file. When you find lines you don't want then just don't write them to the temporary file. When done rename the temporary file as the real file.
To edit a file you have 2 options:
Read in every line and write out those you want to keep
Seek to the part of the file you want deleted and replace the text with spaces (or similar)
You have the first half pretty much done - just write out what you read to a temporary file and delete/rename to make it the original.
For the second option, you can write to the input file at that point if you use an iofstream (be aware of buffering issues). The better option is to use seekp or seekg to get to the right point before overwriting the file.

How to clear a file in append mode in C++

I've a file on which I require multiple operations. Sometimes I just want to append data at the end of the file, sometimes I just want to read from the file, and sometimes, I want to erase all the data and write form the beginning of the file. And then, I again need to append data at the end of file.
I'm using following code:
ofstream writeToTempFile;
ifstream readFromTempFile;
writeToTempFile.open("tempFile.txt", ios::app | ios::out);
readFromTempFile.open("tempFile.txt", ios::in);
// Reading and Appending data to the file
// Now it is time to erase all the previous data and start writing from the beginning
writeToTempFile.open("tempFile.txt", std::ofstream::trunc); // Here I'm removing the contents.
// Write some data to the file
writeToTempFile.open("tempFile.txt", std::ofstream::app); // Using this, I'm again having my file in append mode
But what I've done doesn't work correctly. Please suggest me some solution in C++. ( Not in C)
The problem with the code is:
I wasn't closing the file before I called the method open again on it.
So, close the file before you re-open it with some different permissions.

Write to the start of a textfile in c++

I was looking for an easy way to write something into the first line of an already existing textfile. I tried using ofstream like this:
ofstream textFileWriter("Data/...txt");
if (textFileWriter.is_open())
{
textFileWriter << "HEADER: stuffstuff";
}
But it would delete everything which used to be in that file, even though the ofstream wasn't constructed with std::ofstream::trunc. I cannot use std::ofstream::app, since it is important to write into the first line.
Copying the whole textfile into a vector which has the line already and then writing it back would be my last option, but something I would really like to avoid, since the textfiles are quite large.
You can't simply "append" to the beginning of a file.
The common solution is to open a new (temporary) file, write your new header, write the rest of the original file to the temporary file, and then "rename" (using the OS system calls) the temporary file as the original file.
Or as you say in your question, read the original file into an in-memory buffer (e.g. a vector) and do the modification in that buffer, and then write the buffer to the file.

How to rewrite a new string to a specific location in a text file

Suppose I have a text file with this content: abcdefghk
I want to write a text at position index of 3 with a new text: xyz
In such a way that I will have a new text file: abcxyzghk
How can I achieve this in native C++?
Just use fseek to position and rewrite. If you need to insert, you should use another approach. First, open for appending ("a+t"), set position, and write.
if (FILE* f = fopen("", "a+t"))
{
const char* line = "xyz";
const long int offset = 3;
fseek(f, offset, SEEK_SET);
fputs(line, f);
fclose(f);
}
Note this is C++ code, and I put FILE* f under if scope to avoid accidental use f after fclose. Take care about possible I/O exceptions (fseek outside the EOF).
In general, the only way to modify data in the middle of a text file is
by reading it, modifying the data in memory, and rewriting the entire
file (preferably to something with a different name, then deleting the
original and renaming the new file). If the replacement text is exactly
the same length as the original text, however, and there are no new
lines in either, you can read up to the position, then write at that
position.
Alternatively, you can open the file in binary mode, seek to an
arbitrary position using ostream::seekp, and write there. If the file
is to be treated as text otherwise, the same restrictions concerning new
lines apply in this case as well. And in all cases, the replacement
data must have exactly the same length as the data it replaces.

Avoid contents of an existing file to be overwritten when writing to a file

I am trying to make a game that implements high scores into a .txt file. The question I have is this : when I make a statement such as:
ofstream fout("filename.txt");
Does this create a file with that name, or just look for a file with that name?
The thing is that whenever I start the program anew and make the following statement:
fout << score << endl << player;
it overwrites my previous scores!
Is there any way for me to make it so that the new scores don't overwrite the old ones when I write to the file?
std::ofstream creates a new file by default. You have to create the file with the append parameter.
ofstream fout("filename.txt", ios::app);
If you simply want to append to the end of the file, you can open the file in append mode, so any writing is done at the end of the file and does not overwrite the contents of the file that previously existed:
ofstream fout("filename.txt", ios::app);
If you want to overwrite a specific line of text with data instead of just tacking them onto the end with append mode, you're probably better off reading the file and parsing the data, then fixing it up (adding whatever, removing whatever, editing whatever) and writing it all back out to the file anew.