PDA

View Full Version : QTextStream::seek() not working



derrickbj
5th November 2013, 23:11
Hello,

I'm writing a program in Qt 5.1.1 that reads in a large, specifically formatted text file such as:


Line1
Line2
Heading 1
sub head 1
sub head 2
sub head 3
Heading 2
sub head 1
sub head 2
Heading 3
...

I want my program to perform functions on the sub heading lines within each "heading" section. There is data before and after the "Heading" sections in the file that I just want to ignore.

Here's what I have (simplified):

QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
QTextStream in(&file);
while (! in.atEnd() && !abort) //abort is used in a progress dialog and gets set when the user clicks 'cancel'
{
qApp->processEvents(); //to catch the 'cancel'
str = in.readLine();
if (str.section(" ",0,0) == "Heading")
{
qDebug()<<str;
str = in.readLine();
qint64 pos= in.pos();
while (str.section(" ",0,0) == "")
{
...
//process sub head line
...
str = in.readLine();
qDebug()<<str;
}
if (!in.seek(pos)) QMessageBox::warning(this, "error", "Could not seek in textstream");
}
}

As the program runs, I keep getting the QMessageBox::warning because QTextStream::seek() is returning false. I've tried changing all instances from QTextStream::seek() to QFile::seek() - i.e., instead of in.seek(pos) I tried file.seek(pos), but it basically doesn't do anything and I wind up missing a Heading line. I know that the first heading section is being found and the sub lines are being processed because of the debug output. So the program reads/processes the first set of sub heading lines, reads in the next "Heading 2" line and breaks out of the inner while loop, but is still sitting on that 2nd heading line. So I wanted to seek back a line or two so that it would basically 'ignore' up to "Heading 2" and then process that section, and so on....

Does anybody have any idea why the QTextStream::pos() and QTextStream::seek() combo is not working? Am I just approaching this completely wrong?

Thanks,
--Derrick

ChrisW67
6th November 2013, 04:13
I would be inclined to adjust things a little and dispense with seek():


if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
if (!in.atEnd()) {
str = in.readLine();
do {
if (str.section(" ",0,0) == "Heading") {
qDebug()<< "+" << str;
str = in.readLine();
while (!in.atEnd() && str.section(" ",0,0) == "") {
//process sub head line
qDebug()<< "*" << str;
str = in.readLine();
}
}
else
str = in.readLine();
} while (!in.atEnd());
}
}

You will need to check for correct behaviour with your actual data, but for this input:


Line1
Line2
Heading 1
sub head 1
sub head 2
sub head 3
Heading 2
sub head 1
sub head 2
Heading 3
sub head 1
...
Heading 4
Heading 5
more to ignore

it gives:


+ "Heading 1"
* " sub head 1"
* " sub head 2"
* " sub head 3"
+ "Heading 2"
* " sub head 1"
* " sub head 2"
+ "Heading 3"
* " sub head 1"
+ "Heading 4"
+ "Heading 5"

derrickbj
6th November 2013, 17:16
Thank you for this. I want the same route after posting my comment to get things working and removed seek(). My was was a lot messier and involved some bools to flag when the sub heads were processed. Your way is a lot cleaner and works really well.