>

Use getline to split

Here we use another feature of std::getline: it returns a stream that’s passed to it, and that stream is convertible to bool (or to void*) before C++11. This boolean indicates if no error has occured (so true is no error has occured, false if an error has occured). And that error check includes whether or not the stream is at an end.

So the while loop will nicely stop when the end of the stream (and therefore of the string) has been reached.

Advantages:

  • very clear interface works on any delimiter
  • the delimiter can be specified at runtime

Drawbacks:

  • not standard, though easy to re-use

getline prototype

istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);

Functionality:
Extracts characters from is and stores them into str until the delimitation character delim is found

1
2
3
4
5
6
7
8
9
10
11
12
#include<sstream>

std::vector<std::string> split(const std::string& s, char delimiter){
std::vector<std::string> tokens;
std::string token;
std::istringstream<std::string> tokenStream(s);
while(getline(s, token, delimiter)) {
tokens.push_back(token);
}

return tokens;
}

iterator version

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <Out>
void split(const std::string& s, char delimiter, Out result) {
std::string token;
std::stringstream<std::string> tokenStream;
tokenStream.str(s);
while(getline(s, token, delimiter)) {
*(result++) = token;
}
}

std::vector<std::string> split(const std::string& s, char delimiter) {
std::vector<std::string> tokens;
split(s, delimiter, std::back_inserter(tokens));
return tokens;
}