Parse (split) a string in C++ using string delimiter (standard C++)

C++ParsingSplitTokenTokenize

C++ Problem Overview


I am parsing a string in C++ using the following:

using namespace std;

string parsed,input="text to be parsed";
stringstream input_stringstream(input);

if (getline(input_stringstream,parsed,' '))
{
     // do some processing.
}

Parsing with a single char delimiter is fine. But what if I want to use a string as delimiter.

Example: I want to split:

scott>=tiger

with >= as delimiter so that I can get scott and tiger.

C++ Solutions


Solution 1 - C++

You can use the std::string::find() function to find the position of your string delimiter, then use std::string::substr() to get a token.

Example:

std::string s = "scott>=tiger";
std::string delimiter = ">=";
std::string token = s.substr(0, s.find(delimiter)); // token is "scott"
  • The find(const string& str, size_t pos = 0) function returns the position of the first occurrence of str in the string, or npos if the string is not found.

  • The substr(size_t pos = 0, size_t n = npos) function returns a substring of the object, starting at position pos and of length npos.


If you have multiple delimiters, after you have extracted one token, you can remove it (delimiter included) to proceed with subsequent extractions (if you want to preserve the original string, just use s = s.substr(pos + delimiter.length());):

s.erase(0, s.find(delimiter) + delimiter.length());

This way you can easily loop to get each token.

Complete Example

std::string s = "scott>=tiger>=mushroom";
std::string delimiter = ">=";

size_t pos = 0;
std::string token;
while ((pos = s.find(delimiter)) != std::string::npos) {
    token = s.substr(0, pos);
    std::cout << token << std::endl;
    s.erase(0, pos + delimiter.length());
}
std::cout << s << std::endl;

Output:

scott
tiger
mushroom

Solution 2 - C++

This method uses std::string::find without mutating the original string by remembering the beginning and end of the previous substring token.

#include <iostream>
#include <string>

int main()
{
    std::string s = "scott>=tiger";
    std::string delim = ">=";

    auto start = 0U;
    auto end = s.find(delim);
    while (end != std::string::npos)
    {
        std::cout << s.substr(start, end - start) << std::endl;
        start = end + delim.length();
        end = s.find(delim, start);
    }

    std::cout << s.substr(start, end);
}

Solution 3 - C++

For string delimiter

Split string based on a string delimiter. Such as splitting string "adsf-+qwret-+nvfkbdsj-+orthdfjgh-+dfjrleih" based on string delimiter "-+", output will be {"adsf", "qwret", "nvfkbdsj", "orthdfjgh", "dfjrleih"}

#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

// for string delimiter
vector<string> split (string s, string delimiter) {
    size_t pos_start = 0, pos_end, delim_len = delimiter.length();
    string token;
    vector<string> res;

    while ((pos_end = s.find (delimiter, pos_start)) != string::npos) {
        token = s.substr (pos_start, pos_end - pos_start);
        pos_start = pos_end + delim_len;
        res.push_back (token);
    }

    res.push_back (s.substr (pos_start));
    return res;
}

int main() {
    string str = "adsf-+qwret-+nvfkbdsj-+orthdfjgh-+dfjrleih";
    string delimiter = "-+";
    vector<string> v = split (str, delimiter);

    for (auto i : v) cout << i << endl;

    return 0;
}


Output

adsf
qwret
nvfkbdsj
orthdfjgh
dfjrleih




For single character delimiter

Split string based on a character delimiter. Such as splitting string "adsf+qwer+poui+fdgh" with delimiter "+" will output {"adsf", "qwer", "poui", "fdg"h}

#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

vector<string> split (const string &s, char delim) {
    vector<string> result;
    stringstream ss (s);
    string item;

    while (getline (ss, item, delim)) {
        result.push_back (item);
    }

    return result;
}

int main() {
    string str = "adsf+qwer+poui+fdgh";
    vector<string> v = split (str, '+');

    for (auto i : v) cout << i << endl;

    return 0;
}


Output

adsf
qwer
poui
fdgh

Solution 4 - C++

You can use next function to split string:

vector<string> split(const string& str, const string& delim)
{
    vector<string> tokens;
    size_t prev = 0, pos = 0;
    do
    {
        pos = str.find(delim, prev);
        if (pos == string::npos) pos = str.length();
        string token = str.substr(prev, pos-prev);
        if (!token.empty()) tokens.push_back(token);
        prev = pos + delim.length();
    }
    while (pos < str.length() && prev < str.length());
    return tokens;
}

Solution 5 - C++

A way of doing it with C++20:

#include <iostream>
#include <ranges>
#include <string_view>

int main()
{
	std::string hello = "text to be parsed";
	auto split = hello
		| std::ranges::views::split(' ')
		| std::ranges::views::transform([](auto&& str) { return std::string_view(&*str.begin(), std::ranges::distance(str)); });

	for (auto&& word : split)
	{
		std::cout << word << std::endl;
	}
}

See:
https://stackoverflow.com/a/48403210/10771848
https://en.cppreference.com/w/cpp/ranges/split_view

Solution 6 - C++

You can also use regex for this:

std::vector<std::string> split(const std::string str, const std::string regex_str)
{
    std::regex regexz(regex_str);
    std::vector<std::string> list(std::sregex_token_iterator(str.begin(), str.end(), regexz, -1),
                                  std::sregex_token_iterator());
    return list;
}

which is equivalent to :

std::vector<std::string> split(const std::string str, const std::string regex_str)
{
    std::sregex_token_iterator token_iter(str.begin(), str.end(), regexz, -1);
    std::sregex_token_iterator end;
    std::vector<std::string> list;
    while (token_iter != end)
    {
        list.emplace_back(*token_iter++);
    }
    return list;
}

and use it like this :

#include <iostream>
#include <string>
#include <regex>

std::vector<std::string> split(const std::string str, const std::string regex_str)
{   // a yet more concise form!
    return { std::sregex_token_iterator(str.begin(), str.end(), std::regex(regex_str), -1), std::sregex_token_iterator() };
}

int main()
{
    std::string input_str = "lets split this";
    std::string regex_str = " "; 
    auto tokens = split(input_str, regex_str);
    for (auto& item: tokens)
    {
        std::cout<<item <<std::endl;
    }
}

play with it online! http://cpp.sh/9sumb

you can simply use substrings, characters, etc like normal, or use actual regular expressions to do the splitting.
its also concise and C++11!

Solution 7 - C++

This code splits lines from text, and add everyone into a vector.

vector<string> split(char *phrase, string delimiter){
	vector<string> list;
	string s = string(phrase);
	size_t pos = 0;
	string token;
	while ((pos = s.find(delimiter)) != string::npos) {
	    token = s.substr(0, pos);
	    list.push_back(token);
	    s.erase(0, pos + delimiter.length());
	}
    list.push_back(s);
	return list;
}

Called by:

vector<string> listFilesMax = split(buffer, "\n");

Solution 8 - C++

strtok allows you to pass in multiple chars as delimiters. I bet if you passed in ">=" your example string would be split correctly (even though the > and = are counted as individual delimiters).

EDIT if you don't want to use c_str() to convert from string to char*, you can use substr and find_first_of to tokenize.

string token, mystring("scott>=tiger");
while(token != mystring){
  token = mystring.substr(0,mystring.find_first_of(">="));
  mystring = mystring.substr(mystring.find_first_of(">=") + 1);
  printf("%s ",token.c_str());
}
  

Solution 9 - C++

Answer is already there, but selected-answer uses erase function which is very costly, think of some very big string(in MBs). Therefore I use below function.

vector<string> split(const string& i_str, const string& i_delim)
{
	vector<string> result;
	
	size_t found = i_str.find(i_delim);
	size_t startIndex = 0;

	while(found != string::npos)
	{
		result.push_back(string(i_str.begin()+startIndex, i_str.begin()+found));
		startIndex = found + i_delim.size();
		found = i_str.find(i_delim, startIndex);
	}
	if(startIndex != i_str.size())
		result.push_back(string(i_str.begin()+startIndex, i_str.end()));
	return result;		
}

Solution 10 - C++

I would use boost::tokenizer. Here's documentation explaining how to make an appropriate tokenizer function: http://www.boost.org/doc/libs/1_52_0/libs/tokenizer/tokenizerfunction.htm

Here's one that works for your case.

struct my_tokenizer_func
{
    template<typename It>
    bool operator()(It& next, It end, std::string & tok)
    {
        if (next == end)
            return false;
        char const * del = ">=";
        auto pos = std::search(next, end, del, del + 2);
        tok.assign(next, pos);
        next = pos;
        if (next != end)
            std::advance(next, 2);
        return true;
    }

    void reset() {}
};

int main()
{
    std::string to_be_parsed = "1) one>=2) two>=3) three>=4) four";
    for (auto i : boost::tokenizer<my_tokenizer_func>(to_be_parsed))
        std::cout << i << '\n';
}

Solution 11 - C++

Here's my take on this. It handles the edge cases and takes an optional parameter to remove empty entries from the results.

bool endsWith(const std::string& s, const std::string& suffix)
{
	return s.size() >= suffix.size() &&
		   s.substr(s.size() - suffix.size()) == suffix;
}

std::vector<std::string> split(const std::string& s, const std::string& delimiter, const bool& removeEmptyEntries = false)
{
	std::vector<std::string> tokens;

	for (size_t start = 0, end; start < s.length(); start = end + delimiter.length())
	{
		 size_t position = s.find(delimiter, start);
		 end = position != string::npos ? position : s.length();

		 std::string token = s.substr(start, end - start);
		 if (!removeEmptyEntries || !token.empty())
		 {
			 tokens.push_back(token);
		 }
	}

	if (!removeEmptyEntries &&
		(s.empty() || endsWith(s, delimiter)))
	{
		tokens.push_back("");
	}

	return tokens;
}

Examples

split("a-b-c", "-"); // [3]("a","b","c")

split("a--c", "-"); // [3]("a","","c")

split("-b-", "-"); // [3]("","b","")

split("--c--", "-"); // [5]("","","c","","")

split("--c--", "-", true); // [1]("c")

split("a", "-"); // [1]("a")

split("", "-"); // [1]("")

split("", "-", true); // [0]()

Solution 12 - C++

This should work perfectly for string (or single character) delimiters. Don't forget to include #include <sstream>.

std::string input = "Alfa=,+Bravo=,+Charlie=,+Delta";
std::string delimiter = "=,+"; 
std::istringstream ss(input);
std::string token;
std::string::iterator it;

while(std::getline(ss, token, *(it = delimiter.begin()))) {
    std::cout << token << std::endl; // Token is extracted using '='
    it++;
    // Skip the rest of delimiter if exists ",+"
    while(it != delimiter.end() and ss.peek() == *(it)) { 
        it++; ss.get(); 
    }
}

The first while loop extracts a token using the first character of the string delimiter. The second while loop skips the rest of the delimiter and stops at the beginning of the next token.

Solution 13 - C++

This is a complete method that splits the string on any delimiter and returns a vector of the chopped up strings.

It is an adaptation from the answer from ryanbwork. However, his check for: if(token != mystring) gives wrong results if you have repeating elements in your string. This is my solution to that problem.

vector<string> Split(string mystring, string delimiter)
{
	vector<string> subStringList;
	string token;
	while (true)
	{
		size_t findfirst = mystring.find_first_of(delimiter);
		if (findfirst == string::npos) //find_first_of returns npos if it couldn't find the delimiter anymore
		{
			subStringList.push_back(mystring); //push back the final piece of mystring
			return subStringList;
		}
		token = mystring.substr(0, mystring.find_first_of(delimiter));
		mystring = mystring.substr(mystring.find_first_of(delimiter) + 1);
		subStringList.push_back(token);
	}
	return subStringList;
}

Solution 14 - C++

A very simple/naive approach:

vector<string> words_seperate(string s){
    vector<string> ans;
    string w="";
    for(auto i:s){
        if(i==' '){
           ans.push_back(w);
           w="";
        }
        else{
           w+=i;
        }
    }
    ans.push_back(w);
    return ans;
}

Or you can use boost library split function:

vector<string> result; 
boost::split(result, input, boost::is_any_of("\t"));

Or You can try TOKEN or strtok:

char str[] = "DELIMIT-ME-C++"; 
char *token = strtok(str, "-"); 
while (token) 
{ 
    cout<<token; 
    token = strtok(NULL, "-"); 
} 

Or You can do this:

char split_with=' ';
vector<string> words;
string token; 
stringstream ss(our_string);
while(getline(ss , token , split_with)) words.push_back(token);

Solution 15 - C++

Just in case in the future, someone wants out of the box function of Vincenzo Pii 's answer

#include <vector>
#include <string>


std::vector<std::string> SplitString(
    std::string str,
    std::string delimeter)
{
    std::vector<std::string> splittedStrings = {};
    size_t pos = 0;

    while ((pos = str.find(delimeter)) != std::string::npos)
    {
        std::string token = str.substr(0, pos);
        if (token.length() > 0)
            splittedStrings.push_back(token);
        str.erase(0, pos + delimeter.length());
    }

    if (str.length() > 0)
        splittedStrings.push_back(str);
    return splittedStrings;
}

I also fixed some bugs so that the function won't return an empty string if there is a delimiter at the start or the end of the string

Solution 16 - C++

Since this is the top-rated Stack Overflow Google search result for C++ split string or similar, I'll post a complete, copy/paste runnable example that shows both methods.

splitString uses stringstream (probably the better and easier option in most cases)

splitString2 uses find and substr (a more manual approach)

// SplitString.cpp

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

// function prototypes
std::vector<std::string> splitString(const std::string& str, char delim);
std::vector<std::string> splitString2(const std::string& str, char delim);
std::string getSubstring(const std::string& str, int leftIdx, int rightIdx);


int main(void)
{
  // Test cases - all will pass
  
  std::string str = "ab,cd,ef";
  //std::string str = "abcdef";
  //std::string str = "";
  //std::string str = ",cd,ef";
  //std::string str = "ab,cd,";   // behavior of splitString and splitString2 is different for this final case only, if this case matters to you choose which one you need as applicable
  
  
  std::vector<std::string> tokens = splitString(str, ',');
  
  std::cout << "tokens: " << "\n";
  
  if (tokens.empty())
  {
    std::cout << "(tokens is empty)" << "\n";
  }
  else
  {
    for (auto& token : tokens)
    {
      if (token == "") std::cout << "(empty string)" << "\n";
      else std::cout << token << "\n";
    }
  }
    
  return 0;
}

std::vector<std::string> splitString(const std::string& str, char delim)
{
  std::vector<std::string> tokens;
  
  if (str == "") return tokens;
  
  std::string currentToken;
  
  std::stringstream ss(str);
  
  while (std::getline(ss, currentToken, delim))
  {
    tokens.push_back(currentToken);
  }
  
  return tokens;
}

std::vector<std::string> splitString2(const std::string& str, char delim)
{
  std::vector<std::string> tokens;
  
  if (str == "") return tokens;
  
  int leftIdx = 0;
  
  int delimIdx = str.find(delim);
  
  int rightIdx;
  
  while (delimIdx != std::string::npos)
  {
    rightIdx = delimIdx - 1;
    
    std::string token = getSubstring(str, leftIdx, rightIdx);
    tokens.push_back(token);
    
    // prep for next time around
    leftIdx = delimIdx + 1;
    
    delimIdx = str.find(delim, delimIdx + 1);
  }
  
  rightIdx = str.size() - 1;
  
  std::string token = getSubstring(str, leftIdx, rightIdx);
  tokens.push_back(token);
  
  return tokens;
}

std::string getSubstring(const std::string& str, int leftIdx, int rightIdx)
{
  return str.substr(leftIdx, rightIdx - leftIdx + 1);
}

Solution 17 - C++

Yet another answer: Here I'm using find_first_not_of string function which returns the position of the first character that does not match any of the characters specified in the delim.

size_t find_first_not_of(const string& delim, size_t pos = 0) const noexcept;

Example:

int main()
{
	size_t start = 0, end = 0;
	std::string str = "scott>=tiger>=cat";
	std::string delim = ">=";
	while ((start = str.find_first_not_of(delim, end)) != std::string::npos)
	{
		end = str.find(delim, start); // finds the 'first' occurance from the 'start'
		std::cout << str.substr(start, end - start)<<std::endl; // extract substring
	}
	return 0;
}

Output:

    scott
    tiger
    cat

Solution 18 - C++

I make this solution. It is very simple, all the prints/values are in the loop (no need to check after the loop).

#include <iostream>
#include <string>

using std::cout;
using std::string;

int main() {
	string s = "it-+is-+working!";
	string d = "-+";

	int firstFindI = 0;
	int secendFindI = s.find(d, 0); // find if have any at all
	while (secendFindI != string::npos)
	{
		secendFindI = s.find(d, firstFindI);
		cout << s.substr(firstFindI, secendFindI - firstFindI) << "\n"; // print sliced part
		firstFindI = secendFindI + d.size(); // add to the search index
	}

}

The only downside of this solution is that is doing a search twice in the start.

Solution 19 - C++

This is similar to other answers but it's using string_view. So these are just views for the original string. Similar to the c++20 example. Though this would be a c++17 example. (edit to skip empty matches)

#include <algorithm>
#include <iostream>
#include <string_view>
#include <vector>
std::vector<std::string_view> split(std::string_view buffer,
                                    const std::string_view delimeter = " ") {
  std::vector<std::string_view> ret{};
  std::decay_t<decltype(std::string_view::npos)> pos{};
  while ((pos = buffer.find(delimeter)) != std::string_view::npos) {
    const auto match = buffer.substr(0, pos);
    if (!match.empty()) ret.push_back(match);
    buffer = buffer.substr(pos + delimeter.size());
  }
  if (!buffer.empty()) ret.push_back(buffer);
  return ret;
}
int main() {
  const auto split_values = split("1 2 3 4 5 6 7 8 9     10 ");
  std::for_each(split_values.begin(), split_values.end(),
                [](const auto& str) { std::cout << str << '\n'; });
  return split_values.size();
}

Solution 20 - C++

If you do not want to modify the string (as in the answer by Vincenzo Pii) and want to output the last token as well, you may want to use this approach:

inline std::vector<std::string> splitString( const std::string &s, const std::string &delimiter ){
    std::vector<std::string> ret;
    size_t start = 0;
    size_t end = 0;
    size_t len = 0;
    std::string token;
    do{ end = s.find(delimiter,start); 
        len = end - start;
        token = s.substr(start, len);
        ret.emplace_back( token );
        start += len + delimiter.length();
        std::cout << token << std::endl;
    }while ( end != std::string::npos );
    return ret;
}

Solution 21 - C++

std::vector<std::string> parse(std::string str,std::string delim){
    std::vector<std::string> tokens;
    char *str_c = strdup(str.c_str()); 
    char* token = NULL;
    
    token = strtok(str_c, delim.c_str()); 
    while (token != NULL) { 
        tokens.push_back(std::string(token));  
        token = strtok(NULL, delim.c_str()); 
    }

    delete[] str_c;
   
    return tokens;
}

Solution 22 - C++

Here's a concise split function. I decided to have back to back delimiters return as an empty string but you could easily check that if the substring is empty and not add it to the vector if it is.

#include <vector>
#include <string>
using namespace std;



vector<string> split(string to_split, string delimiter) {
	size_t pos = 0;
	vector<string> matches{};
	do {
		pos = to_split.find(delimiter);
		int change_end;
		if (pos == string::npos) {
			pos = to_split.length() - 1;
			change_end = 1;
		}
		else {
			change_end = 0;
		}
		matches.push_back(to_split.substr(0, pos+change_end));
		
		to_split.erase(0, pos+1);

	}
	while (!to_split.empty());
	return matches;

}

Solution 23 - C++

#include<iostream>
#include<algorithm>
using namespace std;

int split_count(string str,char delimit){
return count(str.begin(),str.end(),delimit);
}

void split(string str,char delimit,string res[]){
int a=0,i=0;
while(a<str.size()){
res[i]=str.substr(a,str.find(delimit));
a+=res[i].size()+1;
i++;
}
}

int main(){

string a="abc.xyz.mno.def";
int x=split_count(a,'.')+1;
string res[x];
split(a,'.',res);

for(int i=0;i<x;i++)
cout<<res[i]<<endl;
  return 0;
}

P.S: Works only if the lengths of the strings after splitting are equal

Solution 24 - C++

Function:

std::vector<std::string> WSJCppCore::split(const std::string& sWhat, const std::string& sDelim) {
    std::vector<std::string> vRet;
    size_t nPos = 0;
    size_t nLen = sWhat.length();
    size_t nDelimLen = sDelim.length();
    while (nPos < nLen) {
        std::size_t nFoundPos = sWhat.find(sDelim, nPos);
        if (nFoundPos != std::string::npos) {
            std::string sToken = sWhat.substr(nPos, nFoundPos - nPos);
            vRet.push_back(sToken);
            nPos = nFoundPos + nDelimLen;
            if (nFoundPos + nDelimLen == nLen) { // last delimiter
                vRet.push_back("");
            }
        } else {
            std::string sToken = sWhat.substr(nPos, nLen - nPos);
            vRet.push_back(sToken);
            break;
        }
    }
    return vRet;
}

Unit-tests:

bool UnitTestSplit::run() {
bool bTestSuccess = true;

    struct LTest {
        LTest(
            const std::string &sStr,
            const std::string &sDelim,
            const std::vector<std::string> &vExpectedVector
        ) {
            this->sStr = sStr;
            this->sDelim = sDelim;
            this->vExpectedVector = vExpectedVector;
        };
        std::string sStr;
        std::string sDelim;
        std::vector<std::string> vExpectedVector;
    };
    std::vector<LTest> tests;
    tests.push_back(LTest("1 2 3 4 5", " ", {"1", "2", "3", "4", "5"}));
    tests.push_back(LTest("|1f|2п|3%^|44354|5kdasjfdre|2", "|", {"", "1f", "2п", "3%^", "44354", "5kdasjfdre", "2"}));
    tests.push_back(LTest("|1f|2п|3%^|44354|5kdasjfdre|", "|", {"", "1f", "2п", "3%^", "44354", "5kdasjfdre", ""}));
    tests.push_back(LTest("some1 => some2 => some3", "=>", {"some1 ", " some2 ", " some3"}));
    tests.push_back(LTest("some1 => some2 => some3 =>", "=>", {"some1 ", " some2 ", " some3 ", ""}));

    for (int i = 0; i < tests.size(); i++) {
        LTest test = tests[i];
        std::string sPrefix = "test" + std::to_string(i) + "(\"" + test.sStr + "\")";
        std::vector<std::string> vSplitted = WSJCppCore::split(test.sStr, test.sDelim);
        compareN(bTestSuccess, sPrefix + ": size", vSplitted.size(), test.vExpectedVector.size());
        int nMin = std::min(vSplitted.size(), test.vExpectedVector.size());
        for (int n = 0; n < nMin; n++) {
            compareS(bTestSuccess, sPrefix + ", element: " + std::to_string(n), vSplitted[n], test.vExpectedVector[n]);
        }
    }

    return bTestSuccess;
}

Solution 25 - C++

As a bonus, here is a code example of a split function and macro that is easy to use and where you can choose the container type :

#include <iostream>
#include <vector>
#include <string>

#define split(str, delim, type) (split_fn<type<std::string>>(str, delim))
 
template <typename Container>
Container split_fn(const std::string& str, char delim = ' ') {
    Container cont{};
    std::size_t current, previous = 0;
    current = str.find(delim);
    while (current != std::string::npos) {
        cont.push_back(str.substr(previous, current - previous));
        previous = current + 1;
        current = str.find(delim, previous);
    }
    cont.push_back(str.substr(previous, current - previous));
    
    return cont;
}

int main() {
    
    auto test = std::string{"This is a great test"};
    auto res = split(test, ' ', std::vector);
    
    for(auto &i : res) {
        std::cout << i << ", "; // "this", "is", "a", "great", "test"
    }
    
    
    return 0;
}

Solution 26 - C++

template<typename C, typename T>
auto insert_in_container(C& c, T&& t) -> decltype(c.push_back(std::forward<T>(t)), void()) {
    c.push_back(std::forward<T>(t));
}
template<typename C, typename T>
auto insert_in_container(C& c, T&& t) -> decltype(c.insert(std::forward<T>(t)), void()) {
    c.insert(std::forward<T>(t));
}
template<typename Container>
Container splitR(const std::string& input, const std::string& delims) {
    Container out;
    size_t delims_len = delims.size();
    auto begIdx = 0u;
    auto endIdx = input.find(delims, begIdx);
    if (endIdx == std::string::npos && input.size() != 0u) {
        insert_in_container(out, input);
    }
    else {
        size_t w = 0;
        while (endIdx != std::string::npos) {
            w = endIdx - begIdx;
            if (w != 0) insert_in_container(out, input.substr(begIdx, w));
            begIdx = endIdx + delims_len;
            endIdx = input.find(delims, begIdx);
        }
        w = input.length() - begIdx;
        if (w != 0) insert_in_container(out, input.substr(begIdx, w));
    }
    return out;
}

Solution 27 - C++

i use pointer arithmetic. inner while for string delimeter if you satify with char delim just remove inner while simply. i hope it is correct. if you notice any mistake or improve please leave the comment.

std::vector<std::string> split(std::string s, std::string delim)
{
    char *p = &s[0];
    char *d = &delim[0];
    std::vector<std::string> res = {""};

    do
    {
        bool is_delim = true;
        char *pp = p;
        char *dd = d;
        while (*dd && is_delim == true)
            if (*pp++ != *dd++)
                is_delim = false;

        if (is_delim)
        {
            p = pp - 1;
            res.push_back("");
        }
        else
            *(res.rbegin()) += *p;
    } while (*p++);

    return res;
}

Solution 28 - C++

Since C++11 it can be done like this:

std::vector<std::string> splitString(const std::string& str,
                                     const std::regex& regex)
{
  return {std::sregex_token_iterator{str.begin(), str.end(), regex, -1}, 
          std::sregex_token_iterator() };
} 

// usually we have a predefined set of regular expressions: then
// let's build those only once and re-use them multiple times
static const std::regex regex1(R"some-reg-exp1", std::regex::optimize);
static const std::regex regex2(R"some-reg-exp2", std::regex::optimize);
static const std::regex regex3(R"some-reg-exp3", std::regex::optimize);

string str = "some string to split";
std::vector<std::string> tokens( splitString(str, regex1) ); 

Notes:

Solution 29 - C++

std::vector<std::string> split(const std::string& s, char c) {
  std::vector<std::string> v;
  unsigned int ii = 0;
  unsigned int j = s.find(c);
  while (j < s.length()) {
    v.push_back(s.substr(i, j - i));
    i = ++j;
    j = s.find(c, j);
    if (j >= s.length()) {
      v.push_back(s.substr(i, s,length()));
      break;
    }
  }
  return v;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTheCrazyProgrammerView Question on Stackoverflow
Solution 1 - C++Vincenzo PiiView Answer on Stackoverflow
Solution 2 - C++moswaldView Answer on Stackoverflow
Solution 3 - C++Arafat HasanView Answer on Stackoverflow
Solution 4 - C++SviatoslavView Answer on Stackoverflow
Solution 5 - C++NoxView Answer on Stackoverflow
Solution 6 - C++HosseinView Answer on Stackoverflow
Solution 7 - C++William Cuervo View Answer on Stackoverflow
Solution 8 - C++ryanbworkView Answer on Stackoverflow
Solution 9 - C++Shubham AgrawalView Answer on Stackoverflow
Solution 10 - C++Benjamin LindleyView Answer on Stackoverflow
Solution 11 - C++Beder Acosta BorgesView Answer on Stackoverflow
Solution 12 - C++hmofradView Answer on Stackoverflow
Solution 13 - C++Amber ElferinkView Answer on Stackoverflow
Solution 14 - C++Shubham Kumar Gupta GgpsView Answer on Stackoverflow
Solution 15 - C++RikuPotatoView Answer on Stackoverflow
Solution 16 - C++cdahmsView Answer on Stackoverflow
Solution 17 - C++SridharKrithaView Answer on Stackoverflow
Solution 18 - C++jacob galamView Answer on Stackoverflow
Solution 19 - C++Robert RussellView Answer on Stackoverflow
Solution 20 - C++user2366975View Answer on Stackoverflow
Solution 21 - C++XLVIIView Answer on Stackoverflow
Solution 22 - C++JadeSpyView Answer on Stackoverflow
Solution 23 - C++user5337845View Answer on Stackoverflow
Solution 24 - C++sea-kgView Answer on Stackoverflow
Solution 25 - C++MagixView Answer on Stackoverflow
Solution 26 - C++GreckView Answer on Stackoverflow
Solution 27 - C++RademView Answer on Stackoverflow
Solution 28 - C++lucaView Answer on Stackoverflow
Solution 29 - C++YileiView Answer on Stackoverflow