Parse a comma separated string in C++
This post will discuss how to parse a comma separated string in C++.
1. Using String Stream
The standard solution to split a comma-delimited string is using std::stringstream. The following demonstrates its usage by reading one character at a time and discarding the immediate character (i.e., comma).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <iostream> #include <vector> #include <string> #include <sstream> using namespace std; vector<int> split(const string &str, char sep) { vector<int> tokens; int i; stringstream ss(str); while (ss >> i) { tokens.push_back(i); if (ss.peek() == sep) { ss.ignore(); } } return tokens; } int main() { string str = "1,2,3,4,5"; char sep = ','; vector<int> tokens = split(str, sep); for (auto &i: tokens) { cout << i << ' '; } return 0; } |
Output:
1 2 3 4 5
The code can be easily extended to handle multiple consecutive separators or whitespace in the string using a while loop instead of the if-statement.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <iostream> #include <vector> #include <string> #include <sstream> using namespace std; vector<int> split(const string &str, char sep) { vector<int> tokens; int i; stringstream ss(str); while (ss >> i) { tokens.push_back(i); while (ss.peek() == sep || ss.peek() == ' ') { ss.ignore(); } } return tokens; } int main() { string str = "1, 2, 3, 4,, 5"; char sep = ','; vector<int> tokens = split(str, sep); for (auto &i: tokens) { cout << i << ' '; } return 0; } |
Output:
1 2 3 4 5
Both above solutions put the results in an integer vector and return it. The code can be easily modified to construct a vector of strings.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#include <iostream> #include <vector> #include <algorithm> #include <string> #include <sstream> using namespace std; vector<string> split(const string &str, char sep) { vector<string> tokens; string token; stringstream ss(str); while (getline(ss, token, ',')) { token.erase(remove_if(token.begin(), token.end(), ::isspace), token.end()); if (!token.empty()) { tokens.push_back(token); } } return tokens; } int main() { string str = "1, 2,3,4,,5"; char sep = ','; vector<string> tokens = split(str, sep); for (auto &s: tokens) { cout << s << ' '; } return 0; } |
Output:
1 2 3 4 5
2. Using std::string::find function
Another solution is to use the std::string::find function to get the next position of the delimiter in the string and insert the substring between the last delimiter position and the current delimiter position into a vector.
The following code demonstrates this by constructing a vector of integers but can be easily modified to construct a vector of strings and handle bad input (consecutive separators, whitespace, etc.).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <iostream> #include <vector> #include <string> using namespace std; vector<int> split(const string &str, char sep) { vector<int> tokens; if (str.empty()) { return tokens; } size_t start = 0, end = 0; while ((end = str.find(sep, start)) != string::npos) { tokens.push_back(stoi(str.substr(start, end - start))); start = end + 1; } tokens.push_back(stoi(str.substr(start))); return tokens; } int main() { string str = "1,2,3,4,5"; char sep = ','; vector<int> tokens = split(str, sep); for (auto &i: tokens) { cout << i << ' '; } return 0; } |
Output:
1 2 3 4 5
3. Using regular expressions
Another plausible solution to parse a comma-delimited string is using a regular expression. Regular expressions are the standardized way to perform a pattern match against a sequence.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> #include <vector> #include <string> #include <regex> using namespace std; int main() { string str = "1, 2, 3,4, 5"; regex reg("[, ]+"); sregex_token_iterator iter(str.begin(), str.end(), reg, -1); sregex_token_iterator end; vector<string> tokens(iter, end); for (auto &s: tokens) { cout << s << ' '; } return 0; } |
Output:
1 2 3 4 5
4. Using Boost library
The Boost C++ library also offers several utility classes for this task. The Boost tokenizer class provides a view of tokens contained in a sequence by interpreting certain characters as separators.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <string> #include <boost/tokenizer.hpp> using namespace std; using namespace boost; int main() { string str = "1,2,3,4,5"; char_separator<char> sep(", "); tokenizer<char_separator<char>> tokens(str, sep); for (string i: tokens) { cout << i << ' '; } return 0; } |
Output:
1 2 3 4 5
The Boost library also provides boost::algorithm::split function to tokenize an expression, which is equivalent to strtok function in C. The boost::algorithm::split function split the input sequence into tokens, delimited by the separators given using a predicate.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <string> #include <vector> #include <iostream> #include <boost/algorithm/string.hpp> using namespace std; using namespace boost::algorithm; int main() { string str = "1,2,3,4,5"; vector<string> tokens; split(tokens, str, is_any_of(",")); for (string i: tokens) { cout << i << ' '; } return 0; } |
Output:
1 2 3 4 5
That’s all about parsing a comma-delimited string in C++.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)