I am trying to store data from a single vector into different vectors and I would like to separate each line into it's respective vector.
A240 001 KERUL 41.857778 52.139167
A240 002 TABAB 40.903333 52.608333
A240 003 KRS 40.040278 53.012222
A240 004 KESEK 39.283333 55.566667
A240 005 INRAK 39.000000 56.300000
A242 001 HR 47.561667 6.732250
This is the layout of a random string and I would like to split it into 5 different vectors so that I would get a vector with [A240, A240, A242,...]
, [001, 002, 003,...]
and so on.
I've thought of regex but I'm not sure how to go about it.
CodePudding user response:
Regex would be good for this, here is an example : I think you can change it to your specific case, e.g. reading your input line by line from a file.
#include <iostream>
#include <string>
#include <regex>
// helper function for showing the content of a vector.
// used to show you the content of each of the 5 vectors generated.
template<typename type_t>
void show(const std::vector<type_t>& values)
{
for (const auto& value : values)
{
std::cout << value << " ";
}
std::cout << std::endl;
}
int main()
{
// I didn't know what the firs 2 entries are so just called them v1, v2
// 5 vectors in total. (you could also opt for 1 vector of a struct holding the data)
std::vector<std::string> v1;
std::vector<std::string> v2;
std::vector<std::string> names;
std::vector<double> longitudes;
std::vector<double> lattitudes;
// This is a regex that will work on the input you gave
// also have a look at regex101.com you can
// test your own regexes there
// \\s matches one or more whitespaces
// group 1 : ([A-Z][0-9]{3}), matches one letter and exactly 3 numbers
// group 2 : ([A-Z]{3}), matches three letters
// group 3 : ([A-Z] ), matches one or more letters
// group 4 : ([0-9] \\.[0-9] ), matches numbers with a . in it
// group 5 : ([0-9] \\.[0-9] ), matches numbers with a . in it
std::regex rx{ "([A-Z][0-9]{3})\\s ([0-9]{3})\\s ([A-Z] )\\s ([0-9] \\.[0-9] )\\s ([0-9] \\.[0-9] )" };
std::smatch match;
std::string input = { "A240 001 KERUL 41.857778 52.139167 A240 002 TABAB 40.903333 52.608333 A240 003 KRS 40.040278 53.012222 A240 004 KESEK 39.283333 55.566667 A240 005 INRAK 39.000000 56.300000 A242 001 HR 47.561667 6.732250" };
// in C you need to explicitly go over repeated occurences
auto begin = input.cbegin();
while (std::regex_search(begin, input.cend(), match, rx))
{
// groups end up in match array, group 1 at index 1, group 2 at index 2, etc..
// group[0] is the whole match, but we don't need it here.
v1.push_back(match[1]);
v2.push_back(match[2]);
names.push_back(match[3]);
// you can also convert the strings to doubles if needed.
longitudes.push_back(std::stod(match[4]));
lattitudes.push_back(std::stod(match[5]));
// skip forward to after match and look further
begin = match.suffix().first;
}
show(v1);
show(v2);
show(names);
show(longitudes);
show(lattitudes);
return 0;
}