C/C++ Arena

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:

#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.

Previous: string search and substrings