03 Dec, 2007, Guest wrote in the 1st comment:
Votes: 0
The following code:

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

std::vector<std::string> string_explode( const std::string& src, char delimiter )
{
std::vector<std::string> exploded;
std::string::size_type token;
std::string working = src;

while( ( token = working.find( delimiter ) ) != std::string::npos )
{
std::cout << "WHOLE STRING: " << working;
std::cout << "SUBSTR: " << working.substr( 0, token );
std::cout << "WORK DONE" << std::endl;
exploded.push_back( working.substr( 0, token ) );
working = working.erase( 0, token );
}

return exploded;
}

int main( int argc, char **argv )
{
std::string test = "Hi.\nI like being split.\nInto multiple pieces.\nBecause I'm just weird that way.\n";

std::vector<std::string> exploded = string_explode( test, '\n' );

std::vector<std::string>::iterator vec;

while( vec != exploded.end() )
{
std::cout << *vec << std::endl;
++vec;
}
}


Produces the following endless output:

Quote
WHOLE STRING:
I like being split.
Into multiple pieces.
Because I'm just weird that way.
SUBSTR: WORK DONE


Obviously I'm doing something wrong. But I can't figure out what.
03 Dec, 2007, David Haley wrote in the 2nd comment:
Votes: 0
You want to erase up to the token position plus one, because you also want to erase the token. Otherwise, you will keep finding a token at position 0.

Also, as a general note, you probably don't want to keep copying the string like that. It'd be a lot more efficient to use positions all the way through.

If your goal is to solve the problem of parsing into a vector, and not just understand the problem, I believe I already provided code for this on the FUSS boards… unfortunately, I believe it was lost during the database death. Let me poke around and see if I still have it somewhere…
03 Dec, 2007, David Haley wrote in the 3rd comment:
Votes: 0
Ah, never mind. The code I was talking about was converting a string into a vector of arguments in the same way that one_argument does. It's about twice as fast as the implementation on the FUSS forums that worked by copying stuff around. (Mine uses position indicators and only copies when absolutely necessary, e.g. when filling the result vector.)
03 Dec, 2007, Guest wrote in the 4th comment:
Votes: 0
The +1 worked for splitting up the string. But the output of the vector in main() segfaulted.

I'd certainly love to know if there's a more efficient way to do this, but it does still need to print what I assigned to the vector as well :P
03 Dec, 2007, David Haley wrote in the 5th comment:
Votes: 0
You don't initialize the iterator:

std::vector<std::string>::iterator vec;

while( vec != exploded.end() )


As for the other way, give me a couple of minutes… :smile:
03 Dec, 2007, David Haley wrote in the 6th comment:
Votes: 0
done…

std::vector<std::string> string_explode( const std::string& src, char delimiter )
{
std::vector<std::string> exploded;

std::string::size_type curPos = 0;
std::string::size_type delimPos;

std::cout << "WHOLE STRING: " << src;

while( ( delimPos = src.find( delimiter, curPos ) ) != std::string::npos )
{
std::string substr = src.substr(curPos, delimPos - curPos);

std::cout << "SUBSTR: " << substr << std::endl;
exploded.push_back( substr );
curPos = delimPos+1;
}
std::cout << "WORK DONE" << std::endl;

return exploded;
}
03 Dec, 2007, David Haley wrote in the 7th comment:
Votes: 0
It should be noted that the last element is not obtained if it is not terminated by the delimiter; if you have something of the form

Hello\nthere\ngoodbye

the 'goodbye' part isn't found. A fairly simple fix would be to loop until curPos goes to npos, instead of delimPos. (a few other small changes needed too)
03 Dec, 2007, Davion wrote in the 8th comment:
Votes: 0
DavidHaley said:
the 'goodbye' part isn't found. A fairly simple fix would be to loop until curPos goes to npos, instead of delimPos. (a few other small changes needed too)


What about just adding something to grab the remainder?
std::vector<std::string> string_explode( const std::string& src, char delimiter )
{
std::vector<std::string> exploded;

std::string::size_type curPos = 0;
std::string::size_type delimPos;

std::cout << "WHOLE STRING: " << src;

while( ( delimPos = src.find( delimiter, curPos ) ) != std::string::npos )
{
std::string substr = src.substr(curPos, delimPos - curPos);

std::cout << "SUBSTR: " << substr << std::endl;
exploded.push_back( substr );
curPos = delimPos+1;
}
//Grab remainder
if(curPos < src.size() )
exploded.push_back(src.substr(curPos, src.size() - curPos) );

std::cout << "WORK DONE" << std::endl;

return exploded;
}
03 Dec, 2007, Davion wrote in the 9th comment:
Votes: 0
Also, another problem that just came to mind- Most MUD strings tend to use \n\r or \r\n, so if your delimiter is '\n' you'll likely have a lot of trailing or preceding \r's. Could lead to some interesting results.
03 Dec, 2007, Guest wrote in the 10th comment:
Votes: 0
Davion, you rock. I wasn't sure how to go about that and was concentrating on fixing other things I've broken in my code :P
03 Dec, 2007, David Haley wrote in the 11th comment:
Votes: 0
<melodrama>There I go rewriting code, solving one logic problem, one segfault, and improving efficiency, and nary a word of thanks to me… Oh, woe be unto me…! :cry:</melodrama>

Sorry, couldn't resist. :biggrin:
03 Dec, 2007, Guest wrote in the 12th comment:
Votes: 0
If it makes you feel better, you're in the code comment :)

// Thanks to David Haley and Davion@MudBytes for assisting in getting this working.
03 Dec, 2007, David Haley wrote in the 13th comment:
Votes: 0
Heh, I was just kidding, but thanks. :smile:

EDIT: I moved the tangent to this new thread
03 Dec, 2007, Guest wrote in the 14th comment:
Votes: 0
Well in the case of this particular function my feeling would be "credit where credit is due" which is what I've got. The function is a collective work of you, Davion, and myself. It's reasonable to assume that if it's posted, the block of code being worked on should contain the final results in order to be useful to anyone.

It might be a whole other thing if someone was posting to get help for code that might be part of a larger application with trade secrets involved, but I doubt many of us here would run the risk of being busted by our employers to do that :)
0.0/14