Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing key/value pairs from a string in C++

I'm working in C++11, no Boost. I have a function that takes as input a std::string that contains a series of key-value pairs, delimited with semicolons, and returns an object constructed from the input. All keys are required, but may be in any order.

Here is an example input string:

Top=0;Bottom=6;Name=Foo;

Here's another:

Name=Bar;Bottom=20;Top=10;

There is a corresponding concrete struct:

struct S 
{
    const uint8_t top;
    const uint8_t bottom;
    const string name; 
}

I've implemented the function by repeatedly running a regular expression on the input string, once per member of S, and assigning the captured group of each to the relevant member of S, but this smells wrong. What's the best way to handle this sort of parsing?

like image 703
Justin R. Avatar asked Dec 30 '25 04:12

Justin R.


2 Answers

For an easy readable solution, you can e.g. use std::regex_token_iterator and a sorted container to distinguish the attribute value pairs (alternatively use an unsorted container and std::sort).

std::regex r{R"([^;]+;)"};
std::set<std::string> tokens{std::sregex_token_iterator{std::begin(s), std::end(s), r}, std::sregex_token_iterator{}};

Now the attribute value strings are sorted lexicographically in the set tokens, i.e. the first is Bottom, then Name and last Top.

Lastly use a simple std::string::find and std::string::substr to extract the desired parts of the string.

Live example

like image 114
Felix Glas Avatar answered Jan 01 '26 18:01

Felix Glas


Do you care about performance or readability? If readability is good enough, then pick your favorite version of split from this question and away we go:

std::map<std::string, std::string> tag_map;

for (const std::string& tag : split(input, ';')) {
    auto key_val = split(input, '=');
    tag_map.insert(std::make_pair(key_val[0], key_val[1]));
}


S s{std::stoi(tag_map["top"]),
    std::stoi(tag_map["bottom"]),
    tag_map["name"]};
like image 29
Barry Avatar answered Jan 01 '26 17:01

Barry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!