0

I'm trying to parse a text file.

The format is :

  1. 6 spaces
  2. string
  3. space + underscore + string
  4. comma + underscore + string
  5. comma + underscore + string

Here is an example : " house1 _rst1,_ab,_aaaa"

This code is working :

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main() {
    ifstream infile("test.txt");
    string line;
    while (getline(infile, line)) {
        string house, param1, param2, param3;
        size_t posP1, posP2, posP3;

        // trim leading whitespaces
        while (isspace(line.at(0)))
            line = line.substr(1,line.length() - 1);

        posP1 = line.find(" _");
        house = line.substr(0, posP1);

        posP2 = line.find(",_", posP1 + 2);
        param1 = line.substr(posP1 + 2, posP2 - posP1 - 2);

        posP3 = line.find(",_", posP2 + 2);
        param2 = line.substr(posP2 + 2, posP3 - posP2 - 2);

        param3 = line.substr(posP3 + 2, line.length() - 2);

        cout << house << " : " << param1 << ", " << param2 + ", " << param3 << endl;
    }
    return 0;
}

i get house1 : rst1, ab, aaaa, but I would like to improve the code using something like stackoverflow.com/a/3555952/3029422, but I do not know how to apply it to my case, when I try :

ifstream infile("test.txt");
string line;
while (getline(infile, line)) {
    string house, param1, param2, param3;

istringstream iss(line);
    if (!(iss >> house >> param1 >> param2 >> param3))
        cout << "not the expected format" << endl;
    else
        cout << house << " : " << param1 << ", " << param2 + ", " << param3 << endl;

I get not the expected format

How can I read each line from the file directly into the variables ? I looks more clean and easy to read this way.

Community
  • 1
  • 1
Ionut
  • 1,729
  • 4
  • 23
  • 50
  • The default parsing only works if things are separated by spaces (whitespace). You have fields separated by commas, its going to take a little more work for you to specify that. – woolstar Sep 20 '14 at 01:23

1 Answers1

1

I find parsing lines like this much easier using streams rather than string processing. I often use std::istringstream to turn the line I read into a stream for parsing.

Perhaps this example code may be useful to you?

#include <string>
#include <sstream>
#include <iostream>

int main()
{
    std::string line = " house1 _rst1,_ab,_aaaa";

    std::string house, param1, param2, param3, skip;

    std::istringstream iss(line);

    iss >> house;
    std::getline(iss, skip, '_');
    std::getline(iss, param1, ',');
    std::getline(iss, skip, '_');
    std::getline(iss, param2, ',');
    std::getline(iss, skip, '_');
    std::getline(iss, param3);

    std::cout << house << " : " << param1 << ", " << param2 + ", " << param3 << '\n';
}

EDIT:

Also you can concatenate stream calls together to form one all-encompasing line parser rather like this:

#include <fstream>
#include <string>
#include <iostream>

int main()
{
    std::ifstream infile("test.txt");

    std::string house, param1, param2, param3;

    // this uses ignore() to skip over the '_' characters and std::getline()
    // to read up to the ',' delimeters.
    while(std::getline(std::getline(std::getline((infile >> house >> std::ws).ignore()
        , param1, ',').ignore(), param2, ',').ignore(), param3))
    {
        std::cout << house << " : " << param1 << ", " << param2 + ", " << param3 << '\n';
    }
}

But that can be difficult to read ;o)

Galik
  • 47,303
  • 4
  • 80
  • 117