This is from my old code base. On the other hand: it comes with unit tests:
Updated today, a more general and standalone Live On Coliru
template <typename Range, typename Value = typename Range::value_type> std::string Join(Range const& elements, const char *const delimiter) { std::ostringstream os; auto b = begin(elements), e = end(elements); if (b != e) { std::copy(b, prev(e), std::ostream_iterator<Value>(os, delimiter)); b = prev(e); } if (b != e) { os << *b; } return os.str(); } template <typename Input, typename Output, typename Value = typename Output::value_type> void Split(char delimiter, Output &output, Input const& input) { using namespace std; for (auto cur = begin(input), beg = cur; ; ++cur) { if (cur == end(input) || *cur == delimiter || !*cur) { output.insert(output.end(), Value(beg, cur)); if (cur == end(input) || !*cur) break; else beg = next(cur); } } }
And some relevant unit tests:
void testSplit() { std::vector<std::string> res; const std::string test = "a test ,string, to,,,be, split,\"up,up\","; TextUtils::Split(',', res, test); UT_EQUAL(10u, res.size()); UT_EQUAL("a test ", res[0]); UT_EQUAL("string", res[1]); UT_EQUAL(" to", res[2]); UT_EQUAL("", res[3]); UT_EQUAL("", res[4]); UT_EQUAL("be", res[5]); UT_EQUAL(" split", res[6]); UT_EQUAL("\"up", res[7]); // Thus making 'split' unusable for parsing UT_EQUAL("up\"", res[8]); // csv files... UT_EQUAL("", res[9]); TextUtils::Split('.', res, "dossier_id"); UT_EQUAL(11u, res.size()); res.clear(); UT_EQUAL(0u, res.size()); TextUtils::Split('.', res, "dossier_id"); UT_EQUAL(1u, res.size()); std::string UseName = res[res.size() - 1]; UT_EQUAL("dossier_id", UseName); } void testJoin() { std::string elements[] = { "aap", "noot", "mies" }; typedef std::vector<std::string> strings; UT_EQUAL("" , TextUtils::Join(strings(), "")); UT_EQUAL("" , TextUtils::Join(strings(), "bla")); UT_EQUAL("aap" , TextUtils::Join(strings(elements, elements + 1), "")); UT_EQUAL("aap" , TextUtils::Join(strings(elements, elements + 1), "#")); UT_EQUAL("aap" , TextUtils::Join(strings(elements, elements + 1), "##")); UT_EQUAL("aapnoot" , TextUtils::Join(strings(elements, elements + 2), "")); UT_EQUAL("aap#noot" , TextUtils::Join(strings(elements, elements + 2), "#")); UT_EQUAL("aap##noot" , TextUtils::Join(strings(elements, elements + 2), "##")); UT_EQUAL("aapnootmies" , TextUtils::Join(strings(elements, elements + 3), "")); UT_EQUAL("aap#noot#mies" , TextUtils::Join(strings(elements, elements + 3), "#")); UT_EQUAL("aap##noot##mies", TextUtils::Join(strings(elements, elements + 3), "##")); UT_EQUAL("aap noot mies", TextUtils::Join(strings(elements, elements + 3), " ")); UT_EQUAL("aapnootmies" , TextUtils::Join(strings(elements, elements + 3), "\0")); UT_EQUAL("aapnootmies" , TextUtils::Join(strings(elements, elements + 3), std::string("\0" , 1).c_str())); UT_EQUAL("aapnootmies" , TextUtils::Join(strings(elements, elements + 3), std::string("\0+", 2).c_str())); UT_EQUAL("aap+noot+mies" , TextUtils::Join(strings(elements, elements + 3), std::string("+\0", 2).c_str())); }
Watch Live On Coliru