16

Possible Duplicates:
C++: How to split a string?
Splitting a string

What is the best way to go about splitting a string up by whitespace in c++?

I'd like to be able to split it based on tab, space, etc. and of course ignore multiple tabs/spaces/etc. in a row as well as not have issues with having those things at the end.

Ultimately, I am going to end up storing this in a vector, but I can easily convert between data types if there is some easy built-in standard library way of splitting.

I am building this on a UNIX machine with g++, not using Microsoft Visual C++

Community
  • 1
  • 1
Brian
  • 2,191
  • 3
  • 20
  • 30

2 Answers2

19

It may be open to question whether it's best, but one really easy way to do this is to put your string into a stringstream, then read the data back out:

// warning: untested code.
std::vector<std::string> split(std::string const &input) { 
    std::istringstream buffer(input);
    std::vector<std::string> ret;

    std::copy(std::istream_iterator<std::string>(buffer), 
              std::istream_iterator<std::string>(),
              std::back_inserter(ret));
    return ret;
}

If you prefer, you can initialize the vector directly from the iterators:

std::vector<std::string> split(std::string const &input) { 
    std::istringstream buffer(input);
    std::vector<std::string> ret((std::istream_iterator<std::string>(buffer)), 
                                 std::istream_iterator<std::string>());
    return ret;
}

Either should work with any reasonable C++ compiler. With C++11, you can clean up the second version a little bit by using brace-initialization instead:

    std::vector<std::string> ret{std::istream_iterator<std::string>(buffer), 
                                 std::istream_iterator<std::string>()};
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • I'd prefer `std::istringstream`, but otherwise it's good. +1 – sbi Feb 16 '10 at 18:34
  • With C++11 you can even clean up **more** with brace initialization: `std::vector ret{std::istream_iterator(buffer), {}};`. And with C++17 you can even say `std::vector` using CTAD :) – sehe Apr 08 '21 at 21:47
7

This is what I use:

/* Tokenizing a string */
    std::vector<std::string> Parser::tokenizer( const std::string& p_pcstStr, char delim )  {
        std::vector<std::string> tokens;
        std::stringstream   mySstream( p_pcstStr );
        std::string         temp;

        while( getline( mySstream, temp, delim ) ) {
            tokens.push_back( temp );
        }

        return tokens;
    } 

Your delim would be a whitespace, p_pcstStr would be the string to tokenize and the return would be a vector with all strings which have a whitespace in between.