#include <cctype>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std::string_literals;
using std::endl; using std::cout; using std::cerr;
auto parse_string_to_int(const std::string& str)
{
std::size_t num_processed = 0;
int val = std::stoi(str, &num_processed, 10);
auto next_non_space = std::find_if(str.begin() + num_processed, str.end(),
[](char ch) { return !std::isspace(ch); });
if (next_non_space != str.end())
throw std::invalid_argument{"extra trailing characters in parse_string_to_int"};
return val;
}
struct Product_token
{
std::string name;
int value;
};
auto get_next_product(std::string::const_iterator& begin, std::string::const_iterator end)
-> Product_token
{
// match `"name" : value "`
auto name_open_quote = std::find(begin, end, '\"');
auto name_close_quote = std::find(name_open_quote + 1, end, '\"');
auto colon = std::find(name_close_quote, end, ':');
auto next_token_open_quote = std::find(colon, end, '\"');
if (name_close_quote == end || name_close_quote == end || colon == end)
{
throw std::invalid_argument{"syntax error on parsing product"};
}
// advance to next token
begin = next_token_open_quote;
return Product_token{{name_open_quote + 1, name_close_quote},
parse_string_to_int({colon + 1, next_token_open_quote})};
}
auto process_products(const std::string& str)
{
auto begin = str.begin();
while (begin != str.end())
{
auto product = get_next_product(begin, str.end());
cout << '"' << product.name << "\" = " << product.value << endl;
}
}
int main()
{
auto str = R"("name1":1234 " name2 " : 23456 "name3" : 12345)"s;
try
{
process_products(str);
}
catch (std::exception& e)
{
cerr << e.what() << endl;
}
}
I2luY2x1ZGUgPGNjdHlwZT4KCiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZz4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ6OnN0cmluZ19saXRlcmFsczsKdXNpbmcgc3RkOjplbmRsOyB1c2luZyBzdGQ6OmNvdXQ7IHVzaW5nIHN0ZDo6Y2VycjsKCmF1dG8gcGFyc2Vfc3RyaW5nX3RvX2ludChjb25zdCBzdGQ6OnN0cmluZyYgc3RyKQp7CiAgICBzdGQ6OnNpemVfdCBudW1fcHJvY2Vzc2VkID0gMDsKICAgIGludCB2YWwgICAgICAgICAgICAgICAgICAgPSBzdGQ6OnN0b2koc3RyLCAmbnVtX3Byb2Nlc3NlZCwgMTApOwoKICAgIGF1dG8gbmV4dF9ub25fc3BhY2UgPSBzdGQ6OmZpbmRfaWYoc3RyLmJlZ2luKCkgKyBudW1fcHJvY2Vzc2VkLCBzdHIuZW5kKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtdKGNoYXIgY2gpIHsgcmV0dXJuICFzdGQ6Omlzc3BhY2UoY2gpOyB9KTsKCiAgICBpZiAobmV4dF9ub25fc3BhY2UgIT0gc3RyLmVuZCgpKQogICAgICAgIHRocm93IHN0ZDo6aW52YWxpZF9hcmd1bWVudHsiZXh0cmEgdHJhaWxpbmcgY2hhcmFjdGVycyBpbiBwYXJzZV9zdHJpbmdfdG9faW50In07CgogICAgcmV0dXJuIHZhbDsKfQoKc3RydWN0IFByb2R1Y3RfdG9rZW4KewogICAgc3RkOjpzdHJpbmcgbmFtZTsKICAgIGludCB2YWx1ZTsKfTsKCmF1dG8gZ2V0X25leHRfcHJvZHVjdChzdGQ6OnN0cmluZzo6Y29uc3RfaXRlcmF0b3ImIGJlZ2luLCBzdGQ6OnN0cmluZzo6Y29uc3RfaXRlcmF0b3IgZW5kKQogICAgLT4gUHJvZHVjdF90b2tlbgp7CiAgICAvLyBtYXRjaCBgIm5hbWUiIDogdmFsdWUgImAKICAgIGF1dG8gbmFtZV9vcGVuX3F1b3RlICAgICAgID0gc3RkOjpmaW5kKGJlZ2luLCBlbmQsICdcIicpOwogICAgYXV0byBuYW1lX2Nsb3NlX3F1b3RlICAgICAgPSBzdGQ6OmZpbmQobmFtZV9vcGVuX3F1b3RlICsgMSwgZW5kLCAnXCInKTsKICAgIGF1dG8gY29sb24gICAgICAgICAgICAgICAgID0gc3RkOjpmaW5kKG5hbWVfY2xvc2VfcXVvdGUsIGVuZCwgJzonKTsKICAgIGF1dG8gbmV4dF90b2tlbl9vcGVuX3F1b3RlID0gc3RkOjpmaW5kKGNvbG9uLCBlbmQsICdcIicpOwoKICAgIGlmIChuYW1lX2Nsb3NlX3F1b3RlID09IGVuZCB8fCBuYW1lX2Nsb3NlX3F1b3RlID09IGVuZCB8fCBjb2xvbiA9PSBlbmQpCiAgICB7CiAgICAgICAgdGhyb3cgc3RkOjppbnZhbGlkX2FyZ3VtZW50eyJzeW50YXggZXJyb3Igb24gcGFyc2luZyBwcm9kdWN0In07CiAgICB9CgogICAgLy8gYWR2YW5jZSB0byBuZXh0IHRva2VuCiAgICBiZWdpbiA9IG5leHRfdG9rZW5fb3Blbl9xdW90ZTsKCiAgICByZXR1cm4gUHJvZHVjdF90b2tlbnt7bmFtZV9vcGVuX3F1b3RlICsgMSwgbmFtZV9jbG9zZV9xdW90ZX0sCiAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZV9zdHJpbmdfdG9faW50KHtjb2xvbiArIDEsIG5leHRfdG9rZW5fb3Blbl9xdW90ZX0pfTsKfQoKYXV0byBwcm9jZXNzX3Byb2R1Y3RzKGNvbnN0IHN0ZDo6c3RyaW5nJiBzdHIpCnsKICAgIGF1dG8gYmVnaW4gPSBzdHIuYmVnaW4oKTsKCiAgICB3aGlsZSAoYmVnaW4gIT0gc3RyLmVuZCgpKQogICAgewogICAgICAgIGF1dG8gcHJvZHVjdCA9IGdldF9uZXh0X3Byb2R1Y3QoYmVnaW4sIHN0ci5lbmQoKSk7CiAgICAgICAgY291dCA8PCAnIicgPDwgcHJvZHVjdC5uYW1lIDw8ICJcIiA9ICIgPDwgcHJvZHVjdC52YWx1ZSA8PCBlbmRsOwogICAgfQp9CgppbnQgbWFpbigpCnsKICAgIGF1dG8gc3RyID0gUiIoIm5hbWUxIjoxMjM0ICAiIG5hbWUyICAiICA6IDIzNDU2ICAibmFtZTMiICA6IDEyMzQ1KSJzOwoKICAgIHRyeQogICAgewogICAgICAgIHByb2Nlc3NfcHJvZHVjdHMoc3RyKTsKICAgIH0KICAgIGNhdGNoIChzdGQ6OmV4Y2VwdGlvbiYgZSkKICAgIHsKICAgICAgICBjZXJyIDw8IGUud2hhdCgpIDw8IGVuZGw7CiAgICB9Cn0=