Заполнить вектор пар двойников с помощью строки XML

#c #xml #c 11

#c #xml #c 11

Вопрос:

У меня есть строка XML, такая как приведенная ниже:

 < thing TYPE="array" UNITS="meters">1.0,1.3,1.2,1.7,1.4,1.9< /thing>
  

Я пытаюсь поместить каждую пару чисел в std::vector< std::pair< double,double > > . По завершении это должно выглядеть примерно так:

< (1.0,1.3), (1.2,1.7), (1.4,1.9) >

Я знаю, что один из способов, которым я мог бы это сделать, — это выполнить поиск каждой запятой в строке, чтобы найти отдельные числа и создать подстроку, затем преобразовать подстроку в double и заполнить одно из чисел в паре. Однако это кажется слишком сложным способом выполнения этой задачи. Есть ли простой способ, которым я мог бы это сделать, возможно, с помощью std::istringstream ? Заранее спасибо!

Комментарии:

1. Это та единственная строка XML, которую вам нужно проанализировать, или есть что-то еще? Если есть что-то большее, тогда вам следует использовать некоторую библиотеку XML. В противном случае, действительно, с вами все должно быть в порядке istringstream .

Ответ №1:

Как насчет использования getline() ?

 #include <vector>
#include <sstream>
#include <iostream>

int main()
 {
   std::vector<std::pair<double, double>> vpss;

   std::string str1, str2;

   std::istringstream iss("1.0,1.3,1.2,1.7,1.4,1.9");

   while ( std::getline(iss, str1, ',') amp;amp; std::getline(iss, str2, ',') )
    {
      std::cout << str1 << ", " << str2 << std::endl;

      vpss.emplace_back(std::stod(str1), std::stod(str2));
    }

   return 0;
 }
  

Другим решением может быть помещение запятой в char переменную

 #include <vector>
#include <sstream>
#include <iostream>

int main()
 {
   std::vector<std::pair<double, double>> vpss;

   char   ch;
   double d1, d2;

   std::istringstream iss("1.0,1.3,1.2,1.7,1.4,1.9");

   while ( iss >> d1 >> ch >> d2 )
    {
      std::cout << d1 << ", " << d2 << std::endl;

      vpss.emplace_back(d1, d2);

      iss >> ch;
    }

   return 0;
 }
  

Ответ №2:

Вы можете использовать регулярное выражение для сбора нужных данных и std::stringstream их анализа

 #include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <regex>
#include <utility>
using namespace std;

int main() 
{
    auto xml_str = R"(< thing TYPE="array" UNITS="meters">1.0,1.3,1.2,1.7,1.4,1.9< /thing>)"s;
    auto r       = regex(R"(>(d.*d)<)"s);
    auto m       = smatch{};
    auto vec     = vector<pair<double, double>>{};

    // Determine if there is a match
    auto beg = cbegin(xml_str);
    while (regex_search(beg, cend(xml_str), m, r)) {
        // Create a string that holds the 1st capture group
        auto str = string(m[1].first, m[1].second);
        auto ss = stringstream{str};
        auto token1 = ""s;
        auto token2 = ""s;
        auto d1 = double{};
        auto d2 = double{};
        // Parse
        while (getline(ss, token1, ',')) {
            getline(ss, token2, ',');
            d1 = stod(token1);
            d2 = stod(token2);
            vec.emplace_back(make_pair(d1, d2));
        }
        // Set new start position for next search
        beg = m[0].second;
    }

    // Print vector content
    auto count = 1;
    for (const autoamp; i : vec) {
        if (count == 3) {
            cout << "(" << i.first << ", " << i.second << ")n";
            count = 1;
        } 
        else {
            cout << "(" << i.first << ", " << i.second << "), ";
            count  ;
        }
    }
}
  

(Скомпилировать с -std=c 14 помощью )

Вывод: (1, 1.3), (1.2, 1.7), (1.4, 1.9)

Live Demo