#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)