Skip to content

Instantly share code, notes, and snippets.

@michaelbacci
Last active January 16, 2020 11:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaelbacci/a9f038e682b83b58017ffc40a5c0f235 to your computer and use it in GitHub Desktop.
Save michaelbacci/a9f038e682b83b58017ffc40a5c0f235 to your computer and use it in GitHub Desktop.
Split string in a very smart way using C++11 variadic templace : split(" str1 ::str2;;3.14,,", " :,", str1_var, str2_var, int_val);
//Copyright Michael Bacci - 2017
//Apache 2.0 license
/**
* Split string in a smart way using C++11 variadic template.
* You can copy/paste this code in your library just citing the source.
*/
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <cassert>
template<typename T>
std::vector<T>
split(const T &str, const T &delimiters) {
std::vector<T> v;
typename T::size_type start, pos = 0;
auto emplace = [&] { if (pos != start) v.emplace_back(str, start, pos - start); };
{
start = 0;
while ((pos = str.find_first_of(delimiters, start)) != T::npos) {
emplace();
start = pos + 1;
}
pos = str.length();
}
emplace();
return v;
}
std::vector<std::string>
split(const std::string &str, const std::string &delimiters) {
return split<std::string>(str, delimiters);
}
template<typename T, typename... TArgs>
std::vector<std::string>
split(const std::string &str, const std::string &delimiters, T &arg, TArgs &...Fargs) {
std::vector<std::string> v;
std::string sub_str;
typename std::string::size_type start, pos;
start = 0;
while ((pos = str.find_first_of(delimiters, start)) != std::string::npos && pos == start)
start = pos + 1;
auto assign_to_arg = [&] (const std::string::size_type pos){
std::string sub(str, start, pos - start);
v.push_back(sub);
std::stringstream ss;
ss << sub;
ss >> arg;
};
if (pos != std::string::npos) {
assign_to_arg(pos);
sub_str = std::string(str.begin() + pos, str.end());
auto sub_v = split(sub_str, delimiters, Fargs...);
v.insert(v.end(), sub_v.begin(), sub_v.end());
} else if (start < str.length()) {
assign_to_arg(str.length());
}
return v;
}
int main() {
std::string str;
int range_min;
int range_max;
float value;
for (auto s : split(" :STRING :3 - 8 -:- 967.314 ", "- :", str, range_min, range_max, value))
std::cout << s << ";";
std::cout << std::endl << str << ";" << range_min << ";" << range_max << ";" << value << ";" << std::endl << std::endl;
std::string first;
int second;
for (auto s : split("::::A 16::3-7,8:", ",- :", first, second))
std::cout << s << ";";
std::cout << std::endl << first << ";" << second << ";" << std::endl;
assert(split("::::", ",- :", first, second).size() == 0);
assert(split(": :COOL1: :COOL2;;COOL3--", " ;,- :", first).size() == 3);
assert(first == "COOL1");
return 0;
}
@michaelbacci
Copy link
Author

The output is:

STRING;3;8;967.314;
STRING;3;8;967.314;

A;16;3;7;8;
A;16;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment