C++ ofstream : Always write onthe 1st line - c++

I would like to know how could I write always to the first line of a file.
I have numbers to share via a text file to another soft, and I want to write those numbers periodically on the first line.
Thanks.
eo

If you want to completely rewrite the file, discarding it's contents then simply use trunc mode. However, if there is any other content that you want to preserve then the easiest way would be to read the file into memory, change the first line and write everything back. I think it wouldn't be possible to change the first line directly unless you are overwriting the same amount of characters.

Look at this two functions:
ostream& seekp ( streampos pos );
ostream& seekp ( streamoff off, ios_bas:seekdir dir );

maybe this solves your problem
ofstream out("foo.txt");
out << "foo";
out << "\r" << "bar";
this will leave a file with only bar in it.
2nd method:
if the file only contains one line you could open it with ofstream::trunc and close it after each write

If the file is not massive then you could write a new new file copying across each line except for the custom first line. Then afterwards replace the original.
void ReplaceFirstLine(string filename)
{
ifstream infile;
ofstream outfile;
infile.open(filename.c_str(), ios_base::in);
outfile.open("tempname.txt", ios_base::out);
bool first = true;
string s;
while (getline(infile, s, '\n'))
{
if (first)
outfile << "my new first line\n";
else
outfile << s << endl;
first = false;
}
infile.close();
outfile.close();
::CopyFileA("tempname.txt", filename.c_str(), FALSE); // or Linux equivalent
}

Related

Append to text file is not working correctly in a loop

The following code is a function that is being called multiple times under runtime. The function contains a for loop where some text is written to a stringstream buffer. The problem is that only the data from the first (or last?) function call is inputed into the text file. I am having trouble to find a way to let the data append to the text file without anything being overwritten, just in a "one after another" manner.
void testItems(const TestObjectList* const testObject) {
std::stringstream objectOutputBuffer;
std::ofstream fileOutput("testlog.txt", std::ios_base::app | std::ios_base::out);
for (itr = testobjects.begin(); itr != testobjects.end(); itr++){
objectOutputBuffer << some stuff getting written to the buffer in the loop << std::endl;
}
fileOutput << objectOutputBuffer.str() << "\n";
//fileOutput.close();
}
Your fileOutput.close() is commented out, closing the file will probably fix.
Try to execute this:
int main() {
std::ofstream f("f.txt");
f << "this will be there\n";
std::ofstream g("f.txt");
g << "this will not\n";
}
The first string will be written to the file but not the second.
I suggest you to move the std::ofstream fileOutput("testlog.txt", std::ios_base::app | std::ios_base::out) outside the function and then pass fileOutput as parameter when you call it.
And when you are finished remember to close the file.
You actually don't need to specify the std::ios::out flag with a std::ofstream object since it already is set by default. If you want to be able to append to the end of your file all you should really need to do is set the std::ios::app flag.
std::ofstream fileOutput("testlog.txt", std::ios::app);
Also while I don't think this is your problem, the newline character doesn't flush your stringstream buffer and force it to write to the file. I would recommend replacing your "\n" with std::endl which does flush the buffer just to be sure.

QT, Write in new line in a file

I have written a code to read from line_Edit in GUI, and write in a file. The code reads the text from line edit and writes the same in the file, but they are printed continuously without any spaces, I want to print the texts written in the line edit in different lines. The file has written text, just want to replace first word of each line by the user entered words.
Code to write in the file:
void MainWindow::on_write_btn_clicked(){
QString str, str2, lin;
str = ui->lineEdit->text();
str2 = ui->lineEdit2->text();
QFile file1("sample.txt");
if(file1.open(QIODevice::ReadWrite | QIODevice::Text)){
QTextStream out(&file1);
out << str;
lin = out.readLine();
out << str2;
file1.seek(30);
file1.close();
}
else
return;
}
File in which we want to write:
If you want the next string to be in a new line in the file you should add the new line character(s) to the stream \n.
Referring to your code you should put:
out << str << '\n' << str2;
which would make the contents of str and str2 appear in consecutive lines.
Instead of the above you could also use the endl manipulator from QTextStream:
out << str << endl << str2;
For this to work properly you need to be opening the file with QIODevice::Text and assure that the endl you are specifying actually comes from QTextStream (not std)
Also note that since you probably only want to write your file there is no need in opening it with ReadWrite option, WriteOnly should be enough.
EDIT according to further details:
To substitute first word from each line of the file you could do the following. Open two files, one which will be read and the second to write the modified data. After iterating though all the lines close the files, remove the original one and rename the output file to replace the original one. Sample implementation:
QFile fileIn("textIn.txt"), fileOut("textOut.txt");
fileIn.open(QFile::ReadOnly); // check result
fileOut.open(QFile::WriteOnly); // check result
QTextStream streamIn(&fileIn), streamOut(&fileOut);
const QChar delimeter = ' ';
while (!streamIn.atEnd())
{
QStringList list = streamIn.readLine().split(delimeter);
if (list.size() > 0) // in case of empty line
list[0] = "substitutedText"; // here put the text you want to set
streamOut << list.join(delimeter) << "\r\n"; // or endl
}
fileIn.close();
fileOut.close();
fileIn.remove(); // check result
fileOut.rename(QFileInfo(fileIn).absoluteFilePath()); // check result
Of course you could try doing the replacement on the original file opened with ReadWrite modifier and setting proper position inside the stream using seek. Although it could get tricky due to different lengths of the read and written data.

How to reverse the output in text file

This is my code for writing input to text file
ofstream fout("C:\\det.txt",ios::app);
fout << input << endl;
fout.close();
this program is working but when i enter more than one input into it its output is like this
Output
four
three
two
in above output two is my last entry and four is my first entry , but i want it in reverse order , the latest input should appear first like
Required output
two // latest entry
three // 2nd latest entry
four // 3rd entry
Put the contents of the file into a vector, reverse the vector and reinsert the strings back into the file.
std::fstream file("C:\\det.txt", std::ios_base::in);
std::vector<std::string> lines;
std::string line;
while (std::getline(file, line))
{
if (!line.empty())
lines.push_back(line);
}
file.close();
file.open("C:\\det.txt", std::ios_base::trunc | std::ios_base::out);
std::copy(lines.rbegin(), lines.rend(), std::ostream_iterator<std::string>(file, "\n"));
If you don't need the file updated as soon as you enter an input, you need a buffer to store the input somewhere (std::vector<std::string> maybe) and then write it to file in reverse order.
Also you can read the whole file and rewrite it using fout << input << endl << readContent; each time but it is not a good way because it will be slow modifying the whole file each time input is given.

Missing line of data using Getline with Ifstream

Ok so this is killing me at the moment cause its such a simple part of my program that just doesn't want to work. I'm reading data from a textfile to use in a GA.
The first getline() works perfectly, but the second one doesn't want to write any data into my string. When i cout the string it doesn't show anything.
Here is the code:
ifstream inFile;
inFile.open(fname.c_str());
char pop[20], mut[20];
inFile.getline(pop,20);
cout << pop;
inFile.getline(mut,20);
cout << mut; //this outputs nothing
Thanks for any help in advance.
A sample form my file:
there is no line between them mutation is the line straight after population
Population size: 30
Mutation: 20
Your file's first line is 20 characters long (19+new line) but pop[20] can only contain 19 (because the last one is reserved for the null terminator '\0').
When istream::getline stops because it has extracted 20-1 characters, it doesn't discard the new line delimiter (because it was never read). So the next getline just reads the end of the first line, discarding the new line.
That's why you get nothing in the second string.
Your problem is that the length of your input line exceeds the length of the buffer which must hold it.
The solution is to not use character arrays. This is C++, use std::string!
std::ifstream inFile;
inFile.open(fname.c_str());
std::string pop;
std::getline(inFile, pop);
cout << pop << "\n";
std::string mut;
std::getline(inFile, mut);
cout << mut << "\n";
I think you need to find out what the problem is. Add error checking code to your getline calls, refactor the (simple) code into a (simple) function, with a (simple) unittest. Possibly, your second line is longer than the assumed 20 characters (null-term included!).
For an idea of what I mean, take a look at this snippet.
try something like
while (getline(in,line,'\n')){
//do something with line
}
or try something like
string text;
string temp;
ifstream file;
file.open ("test_text.txt");
while (!file.eof())
{
getline (file, temp);
text.append (temp); // Added this line
}

Reading from a file, only reads text untill it gets to empty space

I managed to successfully read the text in a file but it only reads until it hits an empty space, for example the text: "Hi, this is a test", cout's as: "Hi,".
Removing the "," made no difference.
I think I need to add something similar to "inFil.ignore(1000,'\n');" to the following bit of code:
inFil>>text;
inFil.ignore(1000,'\n');
cout<<"The file cointains the following: "<<text<<endl;
I would prefer not to change to getline(inFil, variabel); because that would force me to redo a program that is essentially working.
Thank you for any help, this seems like a very small and easily fixed problem but I cant seem to find a solution.
std::ifstream file("file.txt");
if(!file) throw std::exception("Could not open file.txt for reading!");
std::string line;
//read until the first \n is found, essentially reading line by line unti file ends
while(std::getline(file, line))
{
//do something line by line
std::cout << "Line : " << line << "\n";
}
This will help you read the file. I don't know what you are trying to achieve since your code is not complete but the above code is commonly used to read files in c++.
You've been using formatted extraction to extract a single string, once: this means a single word.
If you want a string containing the entire file contents:
std::fstream fs("/path/to/file");
std::string all_of_the_file(
(std::istreambuf_iterator<char>(filestream)),
std::istreambuf_iterator<char>()
);