All very nice solutions so far. Using modern C++ and regex, you can do an all-in-one solution with only very few lines of code.
How? First, we define a regex that either matches an integer OR an integer range. It will look like this
((\d+)-(\d+))|(\d+)
Really very simple. First the range. So, some digits, followed by a hyphen and some more digits. Then the plain integer: Some digits. All digits are put in groups. (braces). The hyphen is not in a matching group.
This is all so easy that no further explanation is needed.
Then we call std::regex_search
in a loop, until all matches are found.
For each match, we check, if there are sub-matches, meaning a range. If we have sub-matches, a range, then we add the values between the sub-matches (inclusive) to the resulting std::vector
.
If we have just a plain integer, then we add only this value.
All this gives a very simple and easy to understand program:
#include <iostream>
#include <string>
#include <vector>
#include <regex>
const std::string test{ "2,3,4,7-9" };
const std::regex re{ R"(((\d+)-(\d+))|(\d+))" };
std::smatch sm{};
int main() {
// Here we will store the resulting data
std::vector<int> data{};
// Search all occureences of integers OR ranges
for (std::string s{ test }; std::regex_search(s, sm, re); s = sm.suffix()) {
// We found something. Was it a range?
if (sm[1].str().length())
// Yes, range, add all values within to the vector
for (int i{ std::stoi(sm[2]) }; i <= std::stoi(sm[3]); ++i) data.push_back(i);
else
// No, no range, just a plain integer value. Add it to the vector
data.push_back(std::stoi(sm[0]));
}
// Show result
for (const int i : data) std::cout << i << '\n';
}
If you should have more questions, I am happy to answer.
Language: C++ 17
Compiled and tested with MS Visual Studio 19 Community Edition