PDA

View Full Version : Write one value per line in text file



babygal
29th November 2010, 07:59
Code :

QString filename = "textfile.txt";
QFile file(filename);
QString val;
float v;

if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
for ( int i =0; i<Results.localresults.size() ; i++)
{
v = Results.localresults.at(i);
val = QString::number(v);
char *valtoAsciidata = val.toAscii().data();
QTextStream out(&file);
out << v << endl ;
}
}

I have written code as above to actually write values to a text file. But it writes the values continuously . What I want is one value to be written in one single line, then the next value on the next line.
How to code in such a way that it writes one value per line ?

SixDegrees
29th November 2010, 08:19
QTextStream is a Qt object; std::endl is a standard library object. I doubt that QTextStream understands std::endl as an end of line character. There's a Qt function endl() that takes a QTextStream as an argument - and probably does what you want - but that's not what you're using.

It's also somewhat surprising that your code works at all, given that you reinitialize 'out' on every loop iteration.

wysota
29th November 2010, 08:45
There is QTextStream::endl as well.

Timoteo
29th November 2010, 09:44
It's also somewhat surprising that your code works at all, given that you reinitialize 'out' on every loop iteration.

You understand that 'out' is actually constructed and destroyed per iteration, right? This is well defined, albeit probably not desirable, behavior. The compiler probably moves the ctor and dtor outside the loop body anyway.

wysota
29th November 2010, 10:09
The compiler probably moves the ctor and dtor outside the loop body anyway.
The compiler cannot change the number of times the constructor/destructor is called. It can only optimize in a situation when there is no constructor defined (i.e. for POD types).


QFile f(...);
f.open(...);
QTextStream stream(&f);
for(int i=0;i<size;++i){
stream << restults.at(i) << endl;
}

SixDegrees
29th November 2010, 10:43
You understand that 'out' is actually constructed and destroyed per iteration, right? This is well defined, albeit probably not desirable, behavior. The compiler probably moves the ctor and dtor outside the loop body anyway.

Very unlikely. There isn't enough information to guide the compiler into hoisting the constructor out of the loop, so the stream is almost certainly being created and destroyed on every iteration. How the stream behaves under such circumstances, I have no idea, but at a minimum there's a large performance hit here, and there is also the possibilty that the file will be written in some unpleasant way due to repeated initializations. I have no idea whether the latter actually occurs here, but it's always best to simplify as much as possible before diving into a fix or modification.

Timoteo
29th November 2010, 14:48
Very unlikely. There isn't enough information to guide the compiler into hoisting the constructor out of the loop, so the stream is almost certainly being created and destroyed on every iteration. How the stream behaves under such circumstances, I have no idea, but at a minimum there's a large performance hit here, and there is also the possibilty that the file will be written in some unpleasant way due to repeated initializations. I have no idea whether the latter actually occurs here, but it's always best to simplify as much as possible before diving into a fix or modification.

Ok, but the point is that you were saying that it shouldn't work as written. If this were the case, then smart pointers would not work either. (Having just typed that I understand why compilers cannot relocate ctor and dtor as wysota mentioned).

wysota
29th November 2010, 14:54
Having just typed that I understand why compilers cannot relocate ctor and dtor as wysota mentioned
This is the simplest example that comes to my mind why it can't be done:

class X {
public:
X() { X::cnt++; }
private:
static int cnt;
};

babygal
30th November 2010, 07:24
I modified the code(as below) but the problem still not solved.The values are still written continuously (and not one value per line as what I want).

QString filename = "textfile.txt";
QFile file(filename);
QString val;
float v;
QTextStream stream(&file);
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))
{ for ( int i =0; i<Results.localresults.size() ; i++)
{ v = Results.localresults.at(i);
val = QString::number(v);
char *valtoAsciidata = val.toAscii().data();
stream << v << endl;
}
}

wysota
30th November 2010, 09:55
What is the point of lines 9 and 10 in the above code?

If you are on windows it might be smart to pass the QIODevice::Text flag while opening the file. Without it you probably get \x0A instead of \x0D\x0A for end of line.

This works fine for me:

#include <QtCore>

int main(){
QFile f("res.txt");
f.open(QFile::WriteOnly|QFile::Truncate|QFile::Tex t);
QTextStream str(&f);
QStringList list;
list << "abc" << "def" << "ghi";
foreach(const QString &s, list){
str << s << endl;
}
return 0;
}

BalaQT
30th November 2010, 09:58
hi,
this code works fine in debian.
may i know , what is the type of Results?

Bala

babygal
1st December 2010, 06:47
What is the point of lines 9 and 10 in the above code?



No point for lines 9 and 10 actually. Can be removed.

Added after 4 minutes:



...
may i know , what is the type of Results?



Results is a public member of class clResults in this scope :


public :
clResults Results;

Added after 12 minutes:




#include <QtCore>

int main(){
QFile f("res.txt");
f.open(QFile::WriteOnly|QFile::Truncate|QFile::Tex t);
QTextStream str(&f);
QStringList list;
list << "abc" << "def" << "ghi";
foreach(const QString &s, list){
str << s << endl;
}
return 0;
}

Your code as above works fine. It can do what I want. Thank you so much for the useful post. :)