Skip to main content
gamedev.net
🔒 Locked

Split std::string

Started by Eriond 5 replies 750+ views
Original Post
Eriond
Eriond
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
SiCrane
SiCrane
I''m going to guess that you keep hitting the same delimiter every loop. Try using firstPos = secondPos + 1;
Eriond
Eriond
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
SiCrane
SiCrane
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.
Eriond
Eriond
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.
SiCrane
SiCrane
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.
Eriond
Eriond
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.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.