No split in the standard library
Python has split() and JavaScript has split(), but the C++ standard library has no function that cuts a string into pieces. Programs build one from the tools that exist. The most common version relies on istringstream, a stream that reads from a string the same way cin reads from the keyboard.
In this lesson the helper is already written for you. You only need to call it. Understanding how it works, though, tells you what it can and can't do.
What the helper does
The function split takes a string and returns a vector<string> with one element per word. Words are separated by whitespace:
string sentence = "hello world foo";
vector<string> words = split(sentence);
// words holds "hello", "world", "foo"
The result has three elements, words[0] is "hello", words[1] is "world", and words.size() is 3.
How it works inside
Here is the helper:
vector<string> split(const string& s) {
vector<string> result;
istringstream iss(s);
string token;
while (iss >> token) result.push_back(token);
return result;
}
It needs <sstream>, <string> and <vector>. Going through it line by line:
- The parameter is
const string& s. The&passes the string by reference, so a long text is not copied, andconstpromises that the function won't change it. istringstream iss(s)creates an input stream whose content is the text ofs.- The loop
while (iss >> token)uses the extraction operator. Each use skips any whitespace, reads characters up to the next whitespace intotoken, and reports whether it succeeded. When the text runs out, the extraction fails and the loop ends. result.push_back(token)adds each word to the end of the vector, which is returned at the end.
What to expect from the output
Because the extraction operator skips whitespace on its own, this approach is forgiving:
- Several spaces in a row, tabs and newlines all count as separators.
- Leading and trailing whitespace produces no empty strings.
split(" hello world foo ")still returns exactly three words. - A string with no words, or an empty string, returns an empty vector.
This is a good fit when the input is a sentence. It is the wrong tool when the separator is another character, such as a comma, or when empty fields matter, as in "a,,b". For those cases, getline(stream, token, ',') reads up to the delimiter you choose and keeps empty fields.
Using the result
A vector of words can be walked with a range-based loop:
for (const string& w : words) {
cout << w << "\n";
}
Use const string& in the loop to avoid copying each word. If you need the number of words, words.size() returns it as an unsigned value, so store it in a size_t and be careful with subtractions such as words.size() - 1 on an empty vector, which wraps around to a huge number.
The exercise, step by step
The editor starts with string sentence = "hello world foo";. The task is to split it into words.
- Declare the result variable. Its type is
vector<string>and its name iswords. - Call the helper with
sentenceas its argument, and assign what it returns towords.
string sentence = "hello world foo";
vector<string> words = split(sentence);
Afterwards words has three elements. split is an ordinary function that you call with the string as an argument. It is not a member of the string, so sentence.split() would not compile.
Common mistakes
- Writing
sentence.split().std::stringhas no such member. - Expecting a punctuation split. Words stay attached to commas and periods:
"hi, there"gives "hi," and "there". - Declaring the result as the wrong type. It is a vector of strings, not an array and not a single string.
- Indexing past the end.
words[3]on a three-element vector is undefined behaviour. Usewords.at(3)to get an exception instead.
Key takeaways
- C++ has no built-in split. The usual helper reads words from an
istringstream. - That helper splits on any run of whitespace and ignores leading and trailing space.
- The result is a
vector<string>, and the helper is called as a free function.