C++ Qt - Reading specific portion of a text file - c++

I want to read a specific portion of a text file in a list widget. I have try different ways and looked online for some solutions but I couldn't find much. Im new using Qt but getting along well with it for the most part.
QFile YearInfo("C:/Users/Documents/info.txt");
YearInfo.open(QIODevice::ReadWrite | QIODevice::Text);
if(YearInfo.isOpen()){
QTextStream in(&YearInfo);
bool readEnabled = false;
QString outputText, startToken = line, endToken = "*"; // line = "2019"
while(!in.atEnd()){
QString getLine = in.readLine();
if(getLine == endToken){
readEnabled = false;
}
if(readEnabled){
outputText.append(getLine + "\n");
}
if(getLine == startToken){
readEnabled = true;
}
}
ui->listWidget->addItem(outputText);
}
YearInfo.flush();
YearInfo.close();
Text File contains:
2019
Position Division Title Date (W.M./R.M./J.R)
*
2020
Position Division Title Date (P.M./V.R/S.T)
*

The code that you have written works as long as you are trying to extract a section of text formatted in the following way
2019
Position Division Title <~~ this line is extracted
Date (W.M./R.M./J.R) <~~ this line is extracted
More stuff <~~ this line is extracted
*
If you have something formatted in the following way
2019 Position Division
Title Date (W.M./R.M./J.R) *
2019 Position Division Title Date (W.M./R.M./J.R) *
nothing will be extracted because you start the extraction when you find a line that contains only the startToken. Same thing for the end token.
You could try to modify the while loop in your code in the following way
while(!in.atEnd()){
QString getLine = in.readLine().trimmed();
if(getLine.startsWith(startToken)){
readEnabled = true;
}
if(readEnabled){
outputText.append(getLine + "\n");
}
if(getLine.endsWith(endToken)){
readEnabled = false;
}
}
Now you are checking if the line startsWith the startToken. Here I also added a trimmed instruction to remove white spaces at the beginning and at the end of each line (just in case...). The same thing is done with endsWith for the endToken.
Also it would be best to open the device in read-only mode, since you are not modifying it anyway
YearInfo.open(QIODevice::ReadOnly | QIODevice::Text);
and also the flush at the end is redundant.
Hope this helps =)

To find the entry of a string, I use QRegExp. Please note that since you have a stopToken like a special symbol for QRegExp it might be changed for "\*:
#include <QRegExp>
#include <QDebug>
QStringList tokenize(QString line, QString start, QString end)
{
QRegExp rx(start+".*"+end);
rx.indexIn(line);
return rx.capturedTexts();
}
void test()
{
qDebug()<<tokenize("2019 Position Division Title Date (W.M./R.M./J.R) *", "2019", "\\*");
// returned ("2019 Position Division Title Date (W.M./R.M./J.R) *")
qDebug()<<tokenize("2020 Position Division Title Date (P.M./V.R/S.T) *", "2019", "\\*");
// returned ("")
}
Your function must be look like this:
...
while(!in.atEnd()){
QString getLine = in.readLine();
QStringList strL = tokenize(getLine, startToken, stopToken);
if (strL.size())
ui->listWidget->addItem(strL[0]);
}

QFile YearInfo("C:/Users/Documents/info.txt");
YearInfo.open(QIODevice::ReadOnly | QIODevice::Text);
if(YearInfo.isOpen()){
QTextStream in(&YearInfo);
bool readEnabled = false;
QString outputText = "", startToken = line.trimmed(), endToken = "*";
while(!in.atEnd()){
QString getLine = in.readLine().trimmed();
if(getLine == startToken){
readEnabled = true;
}
if(readEnabled){
outputText.append(getLine + "\n");
}
if(getLine == endToken){
readEnabled = false;
}
}
ui->listWidget->addItem(outputText);
}
YearInfo.close();

Related

Issue when searching QTableWidget using wildcards

In my Qt C++ application I have several items in a qtablewidget. A QLineEdit along with a button are used by me in order to search the QTableWidget when a particular word is given to the line edit and the search button is clicked. Following is my code:
bool found=false;
QString Line= ui->search->text();
for(int i=0;i<100;i++){
if(ui->tableWidget->item(i,0)->text()== Line){
found = true;
break;
}
}
if(found){
ui->tableWidget->clear();
ui->tableWidget->setItem(0,0,new QTableWidgetItem(Line));
}
else{
QMessageBox::warning(this, tr("Application Name"), tr("The word you are searching does not exist!") );
}
This code works if an exact word in the table widget is given but if I use
ui->tableWidget->item(i,0)->text()=="%"+ Line+"%";
It won't work for the wild card scenario so that I can search even part of a word is given. How can I correct this issue?
The == operator compare two strings and return true if they are exacly equals.
If you want to use wildcards, I suggest to use QRegExp and use QRegExp::Wildcard as pattern syntax.
Example 1:
QString line = "aaaaLINEbbbb";
QRegExp rx("*LINE*");
rx.setPatternSyntax(QRegExp::Wildcard);
rx.exactMatch(line); //should return true
However, if you want to test only if a string contains a substring, I suggest to use bool QString::contains(const QString &str, Qt::CaseSensitivity cs) that can be faster.
Example 2:
QString line = "aaaaLINEbbbb";
QString searchWord = "LINE";
line.contains(searchWord); //should return true
See:
QRegExp
QRegExp::PatternSyntax
Wildcard Matching
QString::contains

QstringList to Qstring conversion issues

I am working on VS2015 with qt framework. In my source code, I have a function for printing in the GUI screen.
This function is called each time something needs to be printed.
It goes like this.
void Trial::Print_MessageBox(QString string)
{
ui.MessagesScreen->appendPlainText(string);
Cursor_Messagebox.movePosition(QTextCursor::End);
ui.MessagesScreen->setTextCursor(Cursor_Messagebox);
ui.MessagesScreen->ensureCursorVisible();
}
// Output in MessageBox
void Trial::Print_MessageBox(QFlags<QNetworkInterface::InterfaceFlag> flags)
{
QString str = QString("Flag %1").arg(flags);
ui.MessagesScreen->appendPlainText(str);
}
The above function has no problems and running well.
Now I am trying to read a text file. This has set of values in no order or size. An example for this:
231, 54, 4 \n
47777, 2211, 676, 9790, 34236, 7898\n
1, 3\n
Objective is to convert these into integers (line by line) and print them in the GUI and also send them (line by line) to other system. So I tried to do it with the following.
void Trial::ReadFile_Data()
{
QFile file("input.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
Print_MessageBox("Error in reading File");
return;
}
QTextStream in(&file);
while (!in.atEnd())
{
QString line = in.readLine();
Print_MessageBox(line);
int conv = line.toInt();
QString str = QString("%1 %2").arg("Values are: ").arg(conv);
Print_MessageBox(str);
QStringList fields = line.split(",");
}
file.close();
}
When I print the "line", it is just printing the same values as in the file. When I do the conversion and printing, I get an error (which is expected) Now I try to remove "," with the help of split then I get QstringList which I cannot use as I have the Qstring function to print(this cant be changed)
I am not getting any pointers from here. Please help me out as this is bugging me since long time.
Just simple...
QStringList::const_iterator constIterator;
for (constIterator = fonts.constBegin(); constIterator != fonts.constEnd();
++constIterator) {
cout << (*constIterator).toLocal8Bit().constData() << endl;
}
where fonts is your QStringlist
Your question reduces to "How do I iterate over a QStringList".
Like this:
// C++11
for (auto field : fields) Print_messageBox(field);
// C++98
foreach (QString field, fields) Print_messageBox(field);
See here for information about how foreach a.k.a Q_FOREACH was implemented.

how to use QRegExp to grep the last line of output of process?

am using QRegExp to grep the last line of the QProcess output via
QString str (process->readAllStandardOutput());
now i want read the last line of str and show that in Statusbar
please how can get the last line only :(
got a working solution using QRegExp
Code sample
QString line(download->readAllStandardOutput());
QString progress;
QString timeRemaining;
if (line.contains(QString("[download]"), Qt::CaseInsensitive)) {
QRegExp rx("(\\d+\\.\\d+%)");
timeRemaining = line.right(5);
rx.indexIn(line);
if(!rx.cap(0).isEmpty()) {
progress = rx.cap(0);
progress.chop(3);
ui->downloadProgressBar->setValue(progress.toInt());
ui->downloadProgressBar->setAlignment(Qt::AlignCenter);
ui->downloadProgressBar->setFormat(timeRemaining);
ui->statusBar->showMessage(line);

Spliting string and displaying in Qtreewidget

My programming knowledge and experience is very poor. I am using this code block to open the desired file when clicked on a push button ;
QString filename = QFileDialog::getOpenFileName();
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!file.atEnd())
{
QByteArray line = file.readLine();
processline(line);
}
And by this line i am showing it on QtextBrowser
void MainWindow::processline(QByteArray paramline)
{
ui->veri_cikis->append(paramline.constData());
}
The data on the file is like this
0;100;0
0;100;24
24;500;24
24;100;6
6;100;6
i have to split the datas by ";" mark and display them on a Qtreewidget columns. How do i do that ? And i have to show each first part on first column and second on second column and so. I have 3 columns in total
I think what you describe is better fit rather to a table view than a tree view. To parse your strings and split them by ';' character you can use QByteArray::split() function. Here is the sample code, that creates and populates table view with items that read from the file:
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTableWidget *table = new QTableWidget;
int row = 0;
while (!file.atEnd()) {
QByteArray line = file.readLine();
QList<QByteArray> tokens = line.split(';');
int column = 0;
row++;
foreach (QByteArray ba, tokens) {
QTableWidgetItem *item = new QTableWidgetItem(ba);
table->setItem(row, column++, item);
}
}

Convert a multiline QString into a one line QString

I have something like this:
void ReadFileAndConvert ()
{
QFile File (Directory + "/here/we/go");
if(File.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream Stream (&File);
QString Text;
do
{
Text = Stream.readLine();
Text = Text.simplified();
// Here I want to convert the multiline QString Text into a oneline QString
// ...
}
The QString Text consists of a multiline Text that I need to convert into a online Text/QString. How can I achieve this? greetings
Put your text into a QStringList, and use QStringList::join(), e.g.
QStringList doc;
[...]
Text = Stream.readLine();
Text = Text.simplified();
doc << Text;
[...]
QString final = doc.join(" ");
You could use the readAll function of QTextStream in order to get a string containing all your text and then use the replace function of QString in order to remove new lines:
QString oneLineText = Stream.readAll().replace("\n"," ").simplified();
If you have a large file it is better to use the readLine function.