25

Possible Duplicate:
Splitting a string in C++

In PHP, the explode() function will take a string and chop it up into an array separating each element by a specified delimiter.

Is there an equivalent function in C++?

Community
  • 1
  • 1
reformed
  • 4,505
  • 11
  • 62
  • 88

2 Answers2

37

Here's a simple example implementation:

#include <string>
#include <vector>
#include <sstream>
#include <utility>

std::vector<std::string> explode(std::string const & s, char delim)
{
    std::vector<std::string> result;
    std::istringstream iss(s);

    for (std::string token; std::getline(iss, token, delim); )
    {
        result.push_back(std::move(token));
    }

    return result;
}

Usage:

auto v = explode("hello world foo bar", ' ');

Note: @Jerry's idea of writing to an output iterator is more idiomatic for C++. In fact, you can provide both; an output-iterator template and a wrapper that produces a vector, for maximum flexibility.

Note 2: If you want to skip empty tokens, add if (!token.empty()).

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • What is the std::move doing in this case? Is it necessary? I compiled without it since I'm not using C++11, and it does just fine. But what is the purpose in this case? –  Nov 21 '14 at 03:56
  • 4
    @user1944429: The move avoids copying the string data. Since you have no more use for it inside the loop, it makes sense for the vector to "steal" that data directly without copying it. – Kerrek SB Nov 21 '14 at 09:21
  • 1
    it misses a case, in the input scenario of "a,b,c,d," it should return 5 values including the last null, but it do not – Alok Saini May 13 '17 at 09:46
  • if need that here what i used, [explode_cpp](http://www.zedwood.com/article/cpp-explode-function) – Alok Saini May 13 '17 at 10:09
  • @AlokSaini: True, the present code has "optional trailing delimiter" semantics rather than what you wanted. The easiest way to fix this would be to add a check if `s.back() == delim` and emit another empty string in that case. – Kerrek SB May 13 '17 at 16:48
  • The standard library really should add this method: `vector std::string::spilt(char delimiter = ' ');` – doctorram Feb 03 '18 at 01:20
  • @doctorram: There's a fairly sophisticated version in Abseil, `absl::StrSplit`. Unlike your version it doesn't presume a specific allocator or output type and it can stop early and all that. – Kerrek SB Feb 03 '18 at 03:46
  • @KerrekSB 's function has 3 known issues, here is a version with 0 known issues: https://pastebin.com/ajAEVQju - the 3 issues are: 1: php's delimiter is a string, not a char (albeit a string containing a single char is supported) but this function use a char for delimiter. 2: php's explode's third (optional) argument is a max split limit, after which anything remaining in the string (even if it contains the delimiter) is concatenated to the last string, but this function doesn't have a third argument. 3: php takes the delimiter as the first argument, not the second argument, (max comment size) – hanshenrik Mar 09 '19 at 20:01
13

The standard library doesn't include a direct equivalent, but it's a fairly easy one to write. Being C++, you don't normally want to write specifically to an array though -- rather, you'd typically want to write the output to an iterator, so it can go to an array, vector, stream, etc. That would give something on this general order:

template <class OutIt>
void explode(std::string const &input, char sep, OutIt output) { 
    std::istringstream buffer(input);

    std::string temp;

    while (std::getline(buffer, temp, sep))
        *output++ = temp;
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111