Archived

This topic is now archived and is closed to further replies.

Eriond

Split std::string

Recommended Posts

I''m trying to write a function to split a std::string but it loops forever in the while loop:
void Split(std::vector<std::string> &out,
		   const std::string &str,
		   const std::string &delim)
{
	std::string::size_type firstPos, secondPos;
	firstPos = str.find_first_of(delim);
	out.push_back(str.substr(0, firstPos));
	while (firstPos != std::string::npos)
	{
		secondPos = str.substr(firstPos).find_first_of(delim);
		out.push_back(str.substr(firstPos + 1, secondPos - firstPos));
		firstPos = secondPos;
	}
}
It probably something obvious, as always when I ask something here

Share this post


Link to post
Share on other sites
I''m going to guess that you keep hitting the same delimiter every loop. Try using firstPos = secondPos + 1;

Share this post


Link to post
Share on other sites
That was the first thing I thought and I tested firstPos = secondPos + 1; and it didn''t work. I have even tried writing everyting down and go throught the loop on paper

Share this post


Link to post
Share on other sites
I didn''t think I needed to mention this, but you also need to change your loop condition because if secondPos was equal to std::string::npos, firstPos wouldn''t be equal to std::string::npos.

Share this post


Link to post
Share on other sites
I''m feeling stupid for asking but change it to what? I''ve tried while (firstPos != std::string::npos + 1) and while(secondPos != std::string::npos) and neither works.

Share this post


Link to post
Share on other sites
Here''s how I would change it:

void Split(std::vector &out,
const std::string &str,
const std::string &delim)
{
std::string::size_type firstPos = 0;
std::string::size_type secondPos = str.find_first_of(delim);
out.push_back(str.substr(firstPos, secondPos));
while (secondPos != std::string::npos)
{
firstPos = secondPos + 1;
secondPos = str.find_first_of(delim, firstPos);
out.push_back(str.substr(firstPos, secondPos - firstPos));
}
}

First off, you were using firstPos and secondPos inconsistently inside the loop and outside the loop, so do some switching around so that firstPos points to the beginning of the string and secondPos points to the end of the string after the first call to find_first_of().

That naturally gives the loop condition (secondPos != std::string::npos).

Then because the order was swapped around before the loop, the firstPos = secondPos + 1 was moved to the top of the loop to maintain consistency.

Then we search the string for the first delimeter after firstPos in the string. I got rid of the substr() before the find_first_of() call because it was inefficient, there''s no reason to create a new string every time through.

Share this post


Link to post
Share on other sites
Thank you very much I didn''t know about the second argument for find_first_of so then I used substr to avoid start from the beginning agin.

Share this post


Link to post
Share on other sites