PDA

View Full Version : Rookie struggling with string manipulation and searching



Jon Heron
16th October 2010, 15:46
Hello All!
I am building a dialog based app for symbian that teaches the user how to tie knots.
I am using a listwidget in the main dialog as a menu that passes the selected knot name to the knot view dialog that iterates through the images and displays them with a QLabel. I also display a text with a description of the selected knot. I have managed to get all that working with the code below. Because some knots like the bowline and sheet bend have a couple of different variants I used a switch function to be sure I get the correct images and description, this all works great though I wonder if this is the correct approach?
I would now like to iterate through the direction text's on a label below the displayed image.
I can make it work by building a separate file for each direction and then iterate through them the same way I am with the images and description documents but it seems cumbersome and I am thinking there must be a better way. :o
I can figure out how to use QString::indexOf(); to find key words in a document but is there a way to extract an entire sentence instead of just a word? That way I could just use one txt document for all the instructions...
All constructive criticism is welcomed!
If this code looks ridiculous go easy on me, I am learning C++ from a book... :p

//recieve knot name and index of selected knot
void knotViewDlg::getIndex(QString knot, int index)
{
//setup d with the path to the resource images
QStringList result; //holds the image filenames
QStringList description; //holds the txt filenames
QDir d(":/knotImages/images");
//populate result with all image names
result = d.entryList();
knot.remove(" "); //remove spaces from string
//search result for key word
QString str1 = knot; //store selected knot name for txts
QString str;
strLst = result.filter(knot, Qt::CaseInsensitive); //fill strLst with filtered images

//figure out which bowline or sheet bend was selected then setup to select proper image files
if(strLst.contains("Bowline_0.gif", Qt::CaseInsensitive))
{
switch(index)
{
case 0:
{
knot = "Bowline_";
break;
}
case 1:
{
knot = "Doublebowline_";
break;
}
case 2:
{
knot = "Bowlineonabight_";
break;
}

default:
break;
};
strLst = result.filter(knot); //setup strLst with the correct image files
strLst.sort();
}

if(strLst.contains("Sheetbend_0.gif", Qt::CaseInsensitive) || (description.contains("DoubleSheetbend_0.gif", Qt::CaseInsensitive)))
{
switch(index)
{
case 3:
{
knot = "Sheetbend_";
break;
}
case 4:
{
knot = "Doublesheetbend_";
break;
}
default:
break;
};
strLst = result.filter(knot);
strLst.sort();
}
strLst.sort();
//set first image before calling timer
str = strLst.at(0);
ui->label->setPixmap(QPixmap(QString::fromUtf8(
":/knotImages/images/").append(str)));
//set first instruction here?

//setup description page
d = (":/images/docs/texts");
result = d.entryList();
description = (result.filter(str1, Qt::CaseInsensitive));
//figure out which bowline or sheet bend was selected then setup to select proper text file
if(description.contains("Bowline.txt", Qt::CaseInsensitive))
{
switch(index)
{
case 0:
{
description.first() = "Bowline.txt";
break;
}
case 1:
{
description.first() = "DoubleBowline.txt";
break;
}
case 2:
{
description.first() = "Bowlineonabight.txt";
break;
}
default:
break;
};
}
if(description.contains("Sheetbend.txt", Qt::CaseInsensitive) || (description.contains("DoubleSheetbend.txt", Qt::CaseInsensitive)))
{
switch(index)
{
case 3:
{
description.first() = "SheetBend.txt";
break;
}
case 4:
{
description.first() = "DoubleSheetbend.txt";
break;
}
default:
break;
};
}

//open appropriate file for descriptions
str = (QString::fromUtf8(":/images/docs/texts/").append(description.at(0)));
QFile inputFile(str);
inputFile.open(QIODevice::ReadOnly);
QTextStream in(&inputFile);
QString line = in.readAll();
inputFile.close();
ui->textEdit->append(line);
ui->tabWidget->setCurrentIndex(1);
ui->textEdit->setFocus();

//open appropriate instructions here?
}
void knotViewDlg::changeImage()
{
QString str = strLst.at(counter);
ui->label->setPixmap(QPixmap(QString::fromUtf8(
":/knotImages/images/").append(str)));
counter++;
if(counter >= (strLst.count()))
{
counter = 0;
}


All constructive comments and help much appreciated!

Cheers,
Jon

SixDegrees
16th October 2010, 17:21
You might consider using XML. That way, you could separate portions of a single document with tags, and easily extract the contents of a single tagged portion.

Or, you could do much the same by embedding tags in your own master document, searching it for whatever tag you choose ('##Tag_Start##', for example, closed with '##Tag_End##'). For a simple project, this may be a better approach than hauling in all of the XML machinery.

gboelter
16th October 2010, 19:17
Hi Jon,

not sure I undrstand your question right ...



... is there a way to extract an entire sentence instead of just a word?
but may be this could be helpfull for you:



QString QString::section ( QChar sep, int start, int end = -1, SectionFlags flags = SectionDefault ) const


A sentence starts with nothing but ends with '.' usually. so secton 0 will be the first, section 2 wil be the second sentence and so on ...

Jon Heron
18th October 2010, 22:42
Thanks guys!

gboelter, that is very helpful!

So I guess I could setup 2 sections, one for the knot category and then have another for the individual directions, perhaps load them into a QStringList to iterate through with the images....
Something like this maybe?


QString instructions;
instructions = line2.section(str1, 1, -1); //load instructions with the selected instructions
QStringList inst; //will hold list of instructions

int tmp(instructions.count(str1, Qt::CaseInsensitive)); //count of instructions
for(int i = 0; i < tmp; i++)
{
inst += instructions.section('|', i, -1);
}

If I format my text file something like this;


Bowline
| bowline Form an overhand loop |
| bowline Pass the end up through the loop from underneath |
| bowline the end behind the standing part |
Bowline

So the first section extracts all the text between the two Bowline tags, the count for the loop uses the lowercase bowline for the count and the second section extracts each instruction into the stringlist for iteration with the image....
Does that make sense?
I will give it a try later tonight once the kids are in bed! :p

Cheers,
Jon

Jon Heron
19th October 2010, 03:23
I was close... ;)
This is what worked;


instructions = line2.section(str1, 1, 1)
int tmp(instructions.count('.') );
for(int i = 0; i < tmp; i++)
{
inst += instructions.section('.', i, i);
qDebug() << "*****" << inst.at(i) << "*******";
}
I had to remove all the carriage returns in the text file also.
Here is the file format;

Bowline Form an overhand loop.Pass the end up through the loop from underneath.Pass the end behind the standing part.Bring the end back down through the loop.To tighten grip the end and the loop in one hand and the standing part in the other. .Be sure to form the knot properly. Bowline
and the output;


***** "Form an overhand loop " *******
***** "Pass the end up through the loop from underneath " *******
***** "Pass the end behind the standing part " *******
***** "Bring the end back down through the loop " *******
***** "To tighten grip the end and the loop in one hand and the standing part in the other " *******
***** " " *******
***** "Be sure to form the knot properly " *******

Thanks again!
Cheers,
Jon