well is there? by string i mean std::string
-
5http://stackoverflow.com/questions/236129/c-how-to-split-a-string – sykora Mar 01 '09 at 15:54
-
3As much as I love C++, I still hate warping my mind around its strings. – isekaijin Mar 01 '09 at 22:05
-
ah right. looks like a duplicate question. i recommend closing this one then and redirect people to the other "c-how-to-split-a-string". what do ya think? – Johannes Schaub - litb Mar 02 '09 at 00:32
-
hmm i'm just reading the other question allows to have spaces in the string. maybe one should not close this one then. not sure anymore :) – Johannes Schaub - litb Mar 02 '09 at 01:50
-
The questioner doesn't specify how he wants to split the strings, so assuming duplicate makes sense unless he makes it clear he wants something different. – Kristopher Johnson Sep 09 '09 at 18:22
-
17How about some of the examples from the following: http://www.codeproject.com/KB/recipes/Tokenizer.aspx They are very efficient and somewhat elegant. The String Toolkit Library makes complex string processing in C++ simple and easy. – Dec 08 '10 at 05:27
10 Answers
Here's a perl-style split function I use:
void split(const string& str, const string& delimiters , vector<string>& tokens)
{
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}

- 4,736
- 2
- 21
- 24
-
1I like this solution. Unlike most other solutions, it doesn't require boost, combines delimiters, supports multiple delimiters, is well documented, and is fairly compact and easy to understand for noobs like me. I'd just change the delimeters parameter to take a default, as in the original: http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html :-) – JJC Feb 21 '12 at 11:41
-
Also, noobs like me should be careful to clear the vector each time they call this function if they expect it to only hold the last set of tokens! (use tokens.clear()). – JJC Feb 21 '12 at 11:42
-
2Old thread that showed up in a search. I would change the signature of `split` to not have a third parameter, and return the `vector
` instead (`tokens` will be a local variable). – Happy Green Kid Naps Mar 10 '14 at 04:05
There's no built-in way to split a string in C++, but boost provides the string algo library to do all sort of string manipulation, including string splitting.

- 28,864
- 15
- 75
- 99
Yup, stringstream.
std::istringstream oss(std::string("This is a test string"));
std::string word;
while(oss >> word) {
std::cout << "[" << word << "] ";
}

- 173,980
- 10
- 155
- 350
-
3This is my work-horse splitter. If you want to split on a delimiter, you can just replace `oss>>word` with `getline(oss, word, ':')` – Eponymous Dec 21 '11 at 02:53
STL strings
You can use string iterators to do your dirty work.
std::string str = "hello world";
std::string::const_iterator pos = std::find(string.begin(), string.end(), ' '); // Split at ' '.
std::string left(str.begin(), pos);
std::string right(pos + 1, str.end());
// Echoes "hello|world".
std::cout << left << "|" << right << std::endl;

- 88,763
- 26
- 134
- 176
void split(string StringToSplit, string Separators)
{
size_t EndPart1 = StringToSplit.find_first_of(Separators)
string Part1 = StringToSplit.substr(0, EndPart1);
string Part2 = StringToSplit.substr(EndPart1 + 1);
}

- 26,650
- 27
- 89
- 114
-
thanks, if this ends up in some opensource program somewhere, will i need to give you credit :) – jimi hendrix Mar 01 '09 at 16:07
The answer is no. You have to break them up using one of the library functions.
Something I use:
std::vector<std::string> parse(std::string l, char delim)
{
std::replace(l.begin(), l.end(), delim, ' ');
std::istringstream stm(l);
std::vector<std::string> tokens;
for (;;) {
std::string word;
if (!(stm >> word)) break;
tokens.push_back(word);
}
return tokens;
}
You can also take a look at the basic_streambuf<T>::underflow()
method and write a filter.

- 108,024
- 16
- 131
- 187
There is no common way doing this.
I prefer the boost::tokenizer, its header only and easy to use.

- 302
- 3
- 7
What the heck... Here's my version...
Note: Splitting on ("XZaaaXZ", "XZ") will give you 3 strings. 2 of those strings will be empty, and won't be added to theStringVector if theIncludeEmptyStrings is false.
Delimiter is not any element in the set, but rather matches that exact string.
inline void
StringSplit( vector<string> * theStringVector, /* Altered/returned value */
const string & theString,
const string & theDelimiter,
bool theIncludeEmptyStrings = false )
{
UASSERT( theStringVector, !=, (vector<string> *) NULL );
UASSERT( theDelimiter.size(), >, 0 );
size_t start = 0, end = 0, length = 0;
while ( end != string::npos )
{
end = theString.find( theDelimiter, start );
// If at end, use length=maxLength. Else use length=end-start.
length = (end == string::npos) ? string::npos : end - start;
if ( theIncludeEmptyStrings
|| ( ( length > 0 ) /* At end, end == length == string::npos */
&& ( start < theString.size() ) ) )
theStringVector -> push_back( theString.substr( start, length ) );
// If at end, use start=maxSize. Else use start=end+delimiter.
start = ( ( end > (string::npos - theDelimiter.size()) )
? string::npos : end + theDelimiter.size() );
}
}
inline vector<string>
StringSplit( const string & theString,
const string & theDelimiter,
bool theIncludeEmptyStrings = false )
{
vector<string> v;
StringSplit( & v, theString, theDelimiter, theIncludeEmptyStrings );
return v;
}

- 8,320
- 27
- 30
C strings
Simply insert a \0
where you wish to split. This is about as built-in as you can get with standard C functions.
This function splits on the first occurance of a char
separator, returning the second string.
char *split_string(char *str, char separator) {
char *second = strchr(str, separator);
if(second == NULL)
return NULL;
*second = '\0';
++second;
return second;
}

- 88,763
- 26
- 134
- 176
-
-
1@strager: This is bad design -- modifying the input. Though this is something strtok() has been doing and has gotten away with. – dirkgently Mar 01 '09 at 16:22
-
@dirkgently, Eh, I misread strtok as strchr with multiple separators. Didn't know much about the function. My bad ... Also, I wouldn't say it's bad design. If documented properly it'd be quite clear, IMO. – strager Mar 01 '09 at 16:33
-
strtok isn't reentrant. However, it would be perfectly reasonable to use a strtok-like facility that starts out by copying the input string into its own buffer, to avoid modifying input or global state. – Tom Mar 01 '09 at 16:55
-
@epochwolf, At the time of posting this, the original question did not mention C strings or std::string. – strager Mar 01 '09 at 20:38
A fairly simple method would be to use the c_str() method of std::string to get a C-style character array, then use strtok() to tokenize the string. Not quite as eloquent as some of the other solutions listed here, but it's easy and works.

- 442
- 1
- 4
- 8
-
2strtok writes into the memory pointed to. c_str() points to memory which must not be written to (invariant of the string class - might silently break things like copy-on-write semantics). the C++ standard forbids it. u can copy to a std::vector first, then you can use strtok though. – Johannes Schaub - litb Mar 02 '09 at 00:47
-
The c_str method returns a const string which points to the internal representation. It's const so you'd also have to strdup it or copy it to a vector. A C++ way was asked for so I'm downvoting this. – hookenz Oct 20 '10 at 08:37