Two methods for two distinct needs when splitting a string
string split inC++ using STL
#include <iostream>
#include <string>
#include <vector>
#include <list>
/*!
\fn splitStr(std::list<std::string>& l, const std::string& seq, char s1, char s2, bool keeptok)
\brief Splits a given std::string ( as param 'seq' ) into token separated by one starting character token and ending the token with a second given separator character.
\param std::list<std::string>& reference to a string list that will receives all the resulting token
\param std::string seq which is the string stream to split
\param char s1 the first separator character that will start the token to be put into the resulting list
\param char s2 the ending separator that will finish the token
\param bool keeptok - optional boolean that is to be given TRUE if the separator characters are needed to be part of the tokens
\return integer that has the number of token in the resulting list
*/
int splitStr(std::list<std::string>& l, const std::string& seq, char s1, char s2, bool keeptok)
{
typedef std::string::size_type ST;
std::vector<int> tok_s1;
std::vector<int> tok_s2;
if(l.size()) l.clear();
ST pos=0, start=0, LEN=seq.size();
while( pos < LEN ){
if(seq[pos] == s1){
start = pos;
if(s2){
while( (pos <LEN) && (seq[pos] != s2)) ++pos;
if(pos <LEN){
tok_s2.push_back(pos);
tok_s1.push_back(start);
start = pos+1;
}
}
else tok_s1.push_back(start);
}
++pos;
}
if(s2){
if( ( tok_s1.size() != tok_s2.size() ) || (tok_s1.size() == 0) ){
//screwed: return the original string
l.push_back(seq);
return 1;
}
if(tok_s1.size()){
if(tok_s1[0]) l.push_back(seq.substr(0, tok_s1[0] - (keeptok ? 0: 1)) );
for(pos = 0; pos < tok_s1.size(); pos++){
if(pos>0){
int c = tok_s1[pos] - tok_s2[pos-1];
if(c > 1) l.push_back(seq.substr( tok_s2[pos-1]+1, c-1));
}
l.push_back(seq.substr( tok_s1[pos], tok_s2[pos]-tok_s1[pos]+1 ));
}
}
if( tok_s2.back() < (LEN-1)) l.push_back(seq.substr(tok_s2.back()+1, (LEN)-(tok_s2.back()+1)));
}
return l.size();
}
/**
\fn splitStr(std::list<std::string>& l, const std::string& seq, const std::string& _1cdelim, bool keeptoken=false, bool _removews=true )
\brief Splits a string into tokens separeted by supplied delimiters as a std::string.
\param std::list<std::string>& L reference to the resulting string tokens
\param std::string seq The string stream to split
\param std::string _lcdelim - a std::string that contains all of the single delimiters
\param bool keeptok -- same as the above function
\param bool removews -- Set to TRUE if requiered to remove white space characters ( space, "\n\r" etc...)
\return integer that has the number of token in the resulting list
*/
int splitStr(std::list<std::string>& L, const std::string& seq, const std::string& _1cdelim, bool keeptoken, bool _removews )
{
typedef std::string::size_type ST;
std::string delims = _1cdelim;
std::string STR;
if(delims.empty()) delims = "\n\r";
if(_removews) delims += " ";
ST pos=0, LEN = seq.size();
while(pos < LEN ){
STR=""; // Init/clear the STR token buffer
// remove any delimiters including optional (white)spaces
while( (delims.find(seq[pos]) != std::string::npos) && (pos < LEN) ) ++pos;
// leave if @eos
if(pos==LEN) return L.size();
// Save token data
while( (delims.find(seq[pos]) == std::string::npos) && (pos < LEN) ) STR += seq[pos++];
// put valid STR buffer into the supplied list
//std::cout << "[" << STR << "]";
if( ! STR.empty() ) L.push_back(STR);
}
return L.size();
}
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
Dani 4,310 The Queen of DaniWeb Administrator Featured Poster Premium Member
rrossenbg 0 Newbie Poster
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.