Этот формат называется «Значение тега».
Наиболее важным критерием, в котором такое кодирование используется в отрасли, является, по-видимому, финансовый протокол FIX (=
для разделителя значений ключа и '\001'
как разделитель позиций). Поэтому, если вы находитесь на оборудовании x86, то лучшим вариантом будет «gsub» для анализа протокола SSE4 FIX и повторное использование открытых источников HFT-магазинов.
Если вы все еще хотите делегировать часть векторизации компилятору и можете сэкономить несколько наносекунд для удобства чтения, то самым изящным решением является сохранение результата в std::string
(данные) + boost::flat_map<boost::string_ref, boost::string_ref>
(просмотр). Парсинг - это вопрос вкуса, while-loop или strtok было бы проще всего проанализировать компилятор. Парсер, основанный на усилении духа, был бы проще всего для человека (знакомого с повышающим духом) читать.
С ++ для цикла на основе раствора
#include <boost/container/flat_map.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/iterator_range_io.hpp>
#include <iostream>
// g++ -std=c++1z ~/aaa.cc
int main()
{
using range_t = boost::iterator_range<std::string::const_iterator>;
using map_t = boost::container::flat_map<range_t, range_t>;
char const sep = ':';
char const dlm = '\n';
// this part can be reused for parsing multiple records
map_t result;
result.reserve(1024);
std::string const input {"hello:world\n bye: world"};
// this part is per-line/per-record
result.clear();
for (auto _beg = begin(input), _end = end(input), it = _beg; it != _end;)
{
auto sep_it = std::find(it, _end, sep);
if (sep_it != _end)
{
auto dlm_it = std::find(sep_it + 1, _end, dlm);
result.emplace(range_t {it, sep_it}, range_t {sep_it + 1, dlm_it});
it = dlm_it + (dlm_it != _end);
}
else throw std::runtime_error("cannot parse");
}
for (auto& x: result)
std::cout << x.first << " => " << x.second << '\n';
return 0;
}
Вы прочитали страницу руководства для 'std :: string' –
Использование, например. ['std :: istringstream'] (http://en.cppreference.com/w/cpp/io/basic_istringstream) и [' std :: getline'] (http://en.cppreference.com/w/cpp/string/basic_string/getline) может быть хорошим началом. Обратите внимание, что 'std :: getline' может использоваться для произвольных разделителей, а не только для строк новой строки. –
Также не беспокойтесь об оптимизации на этом этапе. Сначала убедитесь, что ваша программа работает, а затем * benchmark *, * measure * и * profile *, чтобы найти узкие места и оптимизировать их. Преждевременная оптимизация только сбивает вас с пути. –