Reputation: 5201
What is the best way if you want to read a input like this:
(1,13) { (22,446) (200,66) (77,103) }
(779,22) { } // this is also possible, but always (X,X) in the beginning
I would like to use regular expressions for doing it. But there is little info on usage of reqexp when parsing a string with more than only numbers. Currently im trying something similar with sscanf (from the c-library):
string data;
getline(in, data); // format: (X,X) { (Y,Y)* }
stringstream ss(data);
string point, tmp;
ss >> point; // (X,X)
// (X,X) the reason for three is that they could be more than one digit.
sscanf(point.c_str(), "(%3d,%3d)", &midx, &midy);
int x, y;
while(ss >> tmp) // { (Y,Y) ... (Y,Y) }
{
if(tmp.size() == 5)
{
sscanf(tmp.c_str(), "(%3d,%3d)", &x, &y);
cout << "X: " << x << " Y: " << y << endl;
}
}
The problem is that this does not work, as soon as there is more than one digit sscanf does not read the numbers. So is this the best way to go, or is there a better solution with regexp? I don´t want to use boost or something like that as this is part of a school assignment.
Upvotes: 2
Views: 173
Reputation: 42889
Maybe the following piece of code matches your requirements:
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::smatch m;
std::string str("(1,13) { (22,446) (200,66) (77,103) }");
std::string regexstring = "(\\(\\s*\\d+\\s*,\\s*\\d+\\s*\\))\\s*(\\{)(\\s*\\(\\s*\\d+\\s*,\\s*\\d+\\s*\\)\\s*)*\\s*(\\})";
if (std::regex_match(str, m, std::regex(regexstring))) {
std::cout << "string literal matched" << std::endl;
std::cout << "matches:" << std::endl;
for (std::smatch::iterator it = m.begin(); it != m.end(); ++it) {
std::cout << *it << std::endl;
}
}
return 0;
}
Upvotes: 1
Reputation: 1009
Assuming you're using C++11, you could use something like: std::regex pattern(r"\((\d+),(\d+)\)\s*\{(\s*\(\d+,\d+\))+\s*\}")
(Disclaimer: This hasn't been tested), and then use it like so:
std::smatch match;
while (ss >> tmp) {
if (std::regex_match(tmp, match, pattern)) {
// match[0] contains the first number as a string
// match[1] contains the second number as a string
// match[2] contains the list of points
}
}
Upvotes: 1