Search code examples
c++qtcsvqstandarditemmodel

Get all lines between two specific lines in csv file using Qt


I am reading a csv file in qt using the following code:

QStandardItemModel* readFile()
{
    QFile config_file(FILE_PATH);

    if (config_file.open(QIODevice::ReadOnly)) {
        int lineindex = 0;
        QTextStream in(&config_file);

        while (!in.atEnd()) {

            QString fileLine = in.readLine();
            QStringList lineToken = fileLine.split(",", QString::SkipEmptyParts);
            //ignore commented lines
            if(!fileLine.startsWith("#", Qt::CaseSensitive)){
                for (int j = 0; j < lineToken.size(); j++) {
                    QString value = lineToken.at(j);
                    QStandardItem *item = new QStandardItem(value);
                    fileContent->setItem(lineindex, j, item);
                }
                lineindex++;
            }
        }
        return fileContent;
        config_file.close();
    }
}

My csv is like the following:

TYPE_ES, type_1
subtypes_1, a, b
subtypes_2, 1, 2,3
  subtype_3 1,3,4,5
TYPE_ES, type_2
subtypes_1, x, y
subtypes_2, 4,5,6
  subtype_3 1,3,4,5
TYPE_ES, type_3
subtypes_1, x, y
subtypes_2, 4,5,6
 subtype_3 1,3,4,5

I would like to read and save all the lines in the csv that are between ´TYPE_ES, type_1´, ´TYPE_ES, type_2´ and then between ´TYPE_ES, type_2´, ´TYPE_ES, type_3´ and so on.

For accessing the elements from the QstandardItemModel, I am using the following:

QStringList listDeviceData;
if(fileContent->rowCount() > 0)
{
    for (int row = 0; row < fileContent->rowCount(); row++)
    {
        for (int col = 0; col < fileContent->columnCount(); col++)
        {
            QModelIndex index = fileContent->index(row,col,QModelIndex());
            listDeviceData.append(deviceData->data(index).toString());

        }
        }
    }   

 }

This method allows me to retrieve just elements of one column at a time. However if I were to fetch a set of lines as I mentioned above, how can I parse the QStandardItemModel and achieve this?


Solution

  • May be something like this:

    void readFile(QVector<QStringList>& vectorOfStrings)
    {
        QFile config_file(FILE_PATH);
    
        if (config_file.open(QIODevice::ReadOnly)) {
            QTextStream in(&config_file);
    
            while (!in.atEnd()) {
    
                QString fileLine = in.readLine();
                QStringList lineToken = fileLine.split(",", QString::SkipEmptyParts);
                //ignore commented lines
                if(!fileLine.startsWith("#", Qt::CaseSensitive)){
                    for (int j = 0; j < lineToken.size(); j++) {
                        QString value = lineToken.at(j);
                        if(j == 0 && value == "TYPE_ES"){
                            vectorOfStrings.append(QStringList());
                            break;
                        }
                        if(vectorOfStrings.count() > 0)
                            vectorOfStrings[vectorOfStrings.count() - 1].append(value);
                    }
                }
            }
            config_file.close();
        }
    }
    

    ...

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);    
    
        QVector<QStringList> vectorOfStrings;
        readFile(vectorOfStrings);
    
        return a.exec();
    }
    

    You get all lines between lines with "TYPE_ES".