cyley
cyley

Reputation: 73

Split the data with '\n' character in qt

I have String and I need to split this to new line after every \n . Which is done successfully in following code:

  #include <iostream>
  #include <QtCore>

  int main(int argc, char ** argv)
   {
        QString myString("diskinfo: Node,Description,FreeSpace,Name,Size  \nASHUTOSH-PC,Local Fixed Disk,420935663616,C:,499875049472  \nASHUTOSH-PC,CD-ROM Disc,,D:,  \nASHUTOSH-PC,Local Fixed Disk,324989792256,E:,487687450624  \nASHUTOSH-PC,CD-ROM Disc,0,F:,553459712");

        QStringList myStringList = myString.split("\n");


       for(int index =0;index < myStringList.length();index++)
           {
             std::cout<<myStringList.at(index).toStdString()<<std::endl;
           }
        }

Output of above code is :

    Node,Description,FreeSpace,Name,Size
    OSH-PC,Local Fixed Disk,420942745600,C:,499875049472
    OSH-PC,CD-ROM Disc,,D:,
    OSH-PC,Local Fixed Disk,324861591552,E:,487687450624
    OSH-PC,CD-ROM Disc,0,F:,553459712

Now Next thing I want to do is :

Get the Following output how can it be done:

   Node: OSH-PC Description:Local Fixed Disk, FreeSpace:420942745600, Name:C:,size:499875049472
   Node: OSH-PC Description:CD-ROM, FreeSpace:, Name:D:,size:,

How is this possible in Qt c++?

Upvotes: 2

Views: 1862

Answers (2)

Jonathan Mee
Jonathan Mee

Reputation: 38959

This looks like business logic, and if you're familiar with Multitier Architecture you're aware of the importance of separating that from your presentation layer.

In this case that's a really good thing cause you'll find that makes splitting this into a vector<vector<string>> really easy using a sregex_token_iterator:

const regex re{ "((?:[^\\\\,]|\\\\.)+)(?:,|$)" };
vector<vector<string>> descriptions;

for (auto it = cbegin(myStringList); it != cend(myStringList); ++it) descriptions.emplace_back(vector<string>{ cregex_token_iterator(it->cbegin(), it->cend(), re, 1), cregex_token_iterator() });

for (auto i = 1; i < size(descriptions); ++i) {
    for (auto j = 0; j < size(descriptions.front()) - 1; ++j) {
        cout << descriptions.front()[j] << ": " << descriptions[i][j] << ",\t";
    }
    cout << descriptions.front().back() << ": " << descriptions[i].back() << endl;
}

Live Example

I mentioned in my comment that you're input string does not match your output string. For my code I am requiring at least 1 white space character in between each delimiter (',').

Upvotes: 0

Leontyev Georgiy
Leontyev Georgiy

Reputation: 1315

Well, you just need to split the inner strings of QStringList(as they are QStrings) with ", " separator, and then join the splitted data with the splitted descriptions(first element of QStringList) using basic concatenation. This is my suggestion:

QStringList myStringList = myString.split("\n");

QStringList descriptions = myStringList[0].split(",");
descriptions[0] = descriptions[0].remove(0, descriptions[0].indexOf(" ") + 1);

for(int index = 1;index < myStringList.length();index++)
{
    QStringList data = myStringList[index].split(",");
    QStringList out;
    for(int ind_2 = 0; ind_2 < data.length(); ind_2++)
        out.push_back(descriptions[ind_2] + ": " +data[ind_2]);
    QString out_str = out.join(", ");
    std::cout << out_str.toStdString() << std::endl;
}

JFF, c++11-heavy version :)

#include <iostream>
#include <QtCore>
#include <algorithm>
#include <vector>

int main(int argc, char ** argv)
{
    QString myString("diskinfo: Node,Description,FreeSpace,Name,Size  \nASHUTOSH-PC,Local Fixed Disk,420935663616,C:,499875049472  \nASHUTOSH-PC,CD-ROM Disc,,D:,  \nASHUTOSH-PC,Local Fixed Disk,324989792256,E:,487687450624  \nASHUTOSH-PC,CD-ROM Disc,0,F:,553459712");

    QStringList myStringList = myString.split("\n");

    QStringList descriptions = myStringList[0].split(",");
    descriptions[0] = descriptions[0].remove(0, descriptions[0].indexOf(" ") + 1);

    std::vector<QStringList> data;
    std::transform(myStringList.begin() + 1, myStringList.end(), std::back_inserter(data), [](QString& data_string) {
        return data_string.split(",");
    });

    QStringList out_data;
    std::transform(data.begin(), data.end(), std::back_inserter(out_data), [&descriptions](QStringList& list) {
        QStringList with_desc;
        for(size_t i = 0; i < list.size(); i++)
            with_desc.push_back(descriptions[i] + ": " + list[i]);
        return with_desc.join(",");
    });

    std::cout << out_data.join("\n").toStdString() << std::endl;
}

Upvotes: 1

Related Questions