I know this is a quite easy problem but I just want to solve it for myself once and for all
I would simply like to split a string into an array using a character as
Another way (C++11/boost) for people who like RegEx. Personally I'm a big fan of RegEx for this kind of data. IMO it's far more powerful than simply splitting strings using a delimiter since you can choose to be be a lot smarter about what constitutes "valid" data if you wish.
#include <string>
#include <algorithm> // copy
#include <iterator> // back_inserter
#include <regex> // regex, sregex_token_iterator
#include <vector>
int main()
{
std::string str = "08/04/2012";
std::vector<std::string> tokens;
std::regex re("\\d+");
//start/end points of tokens in str
std::sregex_token_iterator
begin(str.begin(), str.end(), re),
end;
std::copy(begin, end, std::back_inserter(tokens));
}
Is there a reason you don't want to convert a string
to a character array (char*
) ? It's rather easy to call .c_str()
. You can also use a loop and the .find()
function.
string class
string .find()
string .c_str()
Using vectors, strings and stringstream. A tad cumbersome but it does the trick.
std::stringstream test("this_is_a_test_string");
std::string segment;
std::vector<std::string> seglist;
while(std::getline(test, segment, '_'))
{
seglist.push_back(segment);
}
Which results in a vector with the same contents as
std::vector<std::string> seglist{ "this", "is", "a", "test", "string" };
What about erase()
function? If you know exakt position in string where to split, then you can "extract" fields in string with erase()
.
std::string date("01/02/2019");
std::string day(date);
std::string month(date);
std::string year(date);
day.erase(2, string::npos); // "01"
month.erase(0, 3).erase(2); // "02"
year.erase(0,6); // "2019"
I inherently dislike stringstream
, although I'm not sure why. Today, I wrote this function to allow splitting a std::string
by any arbitrary character or string into a vector. I know this question is old, but I wanted to share an alternative way of splitting std::string
.
This code omits the part of the string you split by from the results altogether, although it could be easily modified to include them.
#include <string>
#include <vector>
void split(std::string str, std::string splitBy, std::vector<std::string>& tokens)
{
/* Store the original string in the array, so we can loop the rest
* of the algorithm. */
tokens.push_back(str);
// Store the split index in a 'size_t' (unsigned integer) type.
size_t splitAt;
// Store the size of what we're splicing out.
size_t splitLen = splitBy.size();
// Create a string for temporarily storing the fragment we're processing.
std::string frag;
// Loop infinitely - break is internal.
while(true)
{
/* Store the last string in the vector, which is the only logical
* candidate for processing. */
frag = tokens.back();
/* The index where the split is. */
splitAt = frag.find(splitBy);
// If we didn't find a new split point...
if(splitAt == string::npos)
{
// Break the loop and (implicitly) return.
break;
}
/* Put everything from the left side of the split where the string
* being processed used to be. */
tokens.back() = frag.substr(0, splitAt);
/* Push everything from the right side of the split to the next empty
* index in the vector. */
tokens.push_back(frag.substr(splitAt+splitLen, frag.size()-(splitAt+splitLen)));
}
}
To use, just call like so...
std::string foo = "This is some string I want to split by spaces.";
std::vector<std::string> results;
split(foo, " ", results);
You can now access all the results in the vector at will. Simple as that - no stringstream
, no third party libraries, no dropping back to C!
Boost has the split() you are seeking in algorithm/string.hpp
:
std::string sample = "07/3/2011";
std::vector<string> strs;
boost::split(strs, sample, boost::is_any_of("/"));