I want to parse a string of numbers into a vector of elements. The string consists of blocks of four numbers, separated by ( ) : /
, and each block is separated by a ;
.
Specifically, the string is in this format: int(int):float/float;
, see code sample below. I think I could use a regular expression, but since the data is so structured, I'm sure there must be a more approachable and easier way to parse such a string. I'm using istringstream, but it feels a bit clumsy.
std::string line = "0(0):0/0;1(2):0.01/0.02;2(4):0.02/0.04;3(6):0.03/0.06;"
struct Element {
int a;
int b;
int c;
int d;
};
std::vector<Element> = parse(line);
std::vector<Element> parse(std::string line)
{
std::vector<Element> elements;
std::istringstream iss(line);
while(iss) {
char dummy;
Element element;
iss >> element.a;
iss.read(&dummy,sizeof(dummy)); // (
iss >> element.b;
iss.read(&dummy,sizeof(dummy)); // )
iss.read(&dummy,sizeof(dummy)); // :
iss >> element.c;
iss.read(&dummy,sizeof(dummy)); // /
iss >> element.d;
iss.read(&dummy,sizeof(dummy)); // ;
if (!iss) {break;}
elements.push_back(element);
}
return elements;
}
My questions:
- What would be a good way to parse? Should I use
std::stringstream
and read in number by number and 'chop off' the characters in between? As done in the code sample? - This code has a bug and attempts to read one extra set of values, because
while(iss)
is still true, after the last character has been read in. How to terminate this loop without testing after eachiss>>
? Or more generally, how to loop over extractions from istringstream?