Dinesh Khandelwal
Dinesh Khandelwal

Reputation: 327

How to extract words from std::string given as a pattern?

Consider, We have a text file which consists of 2-D coordinates line by line as:

( 123 , 356 )

( 33 , 3158 )

( 12 , 5 )

and so on.

What is the best way to extract x and y coordinates when we scan this text file line by line?

My method doesn't seem elegant. I'm fetching the line in a std::string and then running a loop to extract the required point:

void find_coordinates(std::string str, int &x, int &y) {
    int i = 2;
    std::string temp;

    while (i < str.length()) {
        if (str[i] == ' ') {
            ++i;
            continue;
        }

        else if (str[i] == ',') {
            x = std::stoi(temp);
            temp.clear();
        }

        else if (str[i] == ')') {
            y = std::stoi(temp);
            return;
        }

        else 
            temp += str[i];

        ++i;
    }
}   


std::ifstream f("file.txt");

while (getline(f, line)) {
    int x, y;
    find_coordinates(line, x, y);
}

Upvotes: 1

Views: 152

Answers (2)

Sunil Kartikey
Sunil Kartikey

Reputation: 525

I would use Boost tokenizer class for this sort of parsing.

#include <iostream>
#include <string>
#include <boost/foreach.hpp>
#include <boost/tokenizer.hpp>

using namespace std;
using namespace boost;

int main(int, char**)
{
   string text = "( 123 , 356 )";

   char_separator<char> sep("(), ");
   tokenizer< char_separator<char> > tokens(text, sep);
   BOOST_FOREACH (const string& t, tokens) {
    cout << t << "." << endl;
  }
 }

Run here

Upvotes: 1

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385194

Sometimes the oldest, simplest solution is the best one:

void find_coordinates(const std::string& str, int& x, int& y)
{
    if (sscanf(str.c_str(), "( %d , %d )", &x, &y) != 2)
       throw std::runtime_error("Parsing failed");
}

(live demo)

This approach is going to fail if your format becomes more flexible, though.

Upvotes: 3

Related Questions