Step 6 of 6
Challenge: split
Splitting a string on a separator is one of the most common text-processing tasks: CSV lines, paths, configuration values, command arguments. It's worth knowing how to write it correctly, because the edge cases trip people up.
The approach
Keep a start position (initially 0). Repeatedly find the separator from start:
- If found at position
p, the piece iss.substr(start, p - start). Add it, then continue fromstart = p + 1. - If not found, the rest of the string,
s.substr(start), is the last piece. Add it and stop.
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> words(const std::string& s) {
std::vector<std::string> out;
std::string current;
for (char c : s) {
if (c == ' ') {
if (!current.empty()) out.push_back(current);
current.clear();
} else {
current += c;
}
}
if (!current.empty()) out.push_back(current);
return out;
}
int main() {
auto w = words(" the quick brown fox ");
std::cout << w.size() << ":";
for (const auto& x : w) std::cout << " [" << x << "]";
std::cout << "\n";
}
4: [the] [quick] [brown] [fox]
This example shows a different approach (building each piece character by character) for a different rule: splitting into words, where runs of spaces are skipped and empty pieces are dropped.
Your rule is different: keep empty pieces
For CSV-like data, "a,,b" has three fields, the middle one empty, and "" is one empty field. Dropping empty pieces would shift columns and corrupt data. With the find-based approach, the rule "the text after the last separator is always one more piece" gives exactly these results: n separators always produce n + 1 pieces. Test your function on "a,,b", "", "," and "a," before submitting.
Your turn: write std::vector<std::string> split(const std::string& s, char sep) that breaks a string at every sep.
split("a,b,c", ',')gives{"a", "b", "c"}split("a,,b", ',')gives{"a", "", "b"}(empty pieces are kept)split("", ',')gives{""}