Well, I wonder HOW to make an explode() function from PHP in C++

For those who don't know.

explode($separator, $string) breaks given $string through given $separator

for example:

$string = "Hello world!";
$result = explode(" ", $string);

echo $result[0]; //IT will give us HELLO word
echo $result[1]; //IT will give us WORLD! word

Each word is put into the array and has own index.

now... have someone any idea how to make it in C++ ?

Do not show any examples from this forum.
I already saw all and all are bad (doesn't match to the requirements)

Member Avatar for iamthwee

Well what have you tried? Show some effort.

PHP is open source. You can browse through its source code and see the way it is implemented.

> Both are not what I wanted to...
Great, out of all possible solutions, you've narrowed the field by two solutions.

Still leaves a hell of a lot of possible solutions out there.

Care to actually put some effort in towards showing what your ideal solution might be, rather than repeatedly posting "not it".

We're not here to guess what you're thinking, nor play "20 questions" to find such stuff out.

@Up

1. Get string wich user provided
2. break it through given separator
3. Each breaked put into array. Give to each word own index nr.
4. Each variable that function belongs to gives each word
e.x

char func = explode(char separator, char string);
cout func[0]; //1st word
cout func[1]; //2nd word

That's what you wanted ?

Member Avatar for iamthwee

Is the separator a string or a char?

you do not have to make one. it is available in libraries.
either the boost string algorithms or the boost tokenizer could be used.

here is an example using the boost string algorithms split. as you can notice, c++ libraries are
far more powerful and expressive. in this example, we are splitting on different criteria and placing the
result into different types of containers. and we are using one function: split to do all this.

#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/lambda/lambda.hpp>
#include <vector>
#include <list>
#include <deque>
#include <algorithm>
using namespace std;
using namespace boost;
using namespace boost::lambda;

template<typename C> inline void print( const C& cntr )
{ for_each( cntr.begin(), cntr.end(), cout << constant('[') << _1 << "]  " ) ; }

int main()
{
  string str = "ab+*%cde4fg*hijk   lmno%+pqr3stu--vwx yz   "
                       "ab0cde+fgh2ij345klm4nop5qr7st" ;

  vector<string> vec ;
  split( vec, str, is_any_of("+*%-"), token_compress_on ) ; 
  print(vec) ; cout << '\n' ; 

  list<string> lst ;
  split( lst, str, is_from_range('2', '6') ) ; // token_compress_off by default
  print(lst) ; cout << '\n' ; 

  deque<string> deq ;
  split( deq, str, is_space(), token_compress_on ) ; 
  print(deq) ; cout << '\n' ; 
}

and this is the output:
g++ -Wall -std=c++98 -I/usr/local/include split.cpp ; ./a.out
[ab] [cde4fg] [hijk lmno] [pqr3stu] [vwx yz ab0cde] [fgh2ij345klm4nop5qr7st]
[ab+*%cde] [fg*hijk lmno%+pqr] [stu--vwx yz ab0cde+fgh] [ij] [] [] [klm] [nop] [qr7st]
[ab+*%cde4fg*hijk] [lmno%+pqr3stu--vwx] [yz] [ab0cde+fgh2ij345klm4nop5qr7st]


ps: i should qualify my first statement; you do not have to make one; unless your idea is to learn
programming.

commented: Really nice example, thx +3
Member Avatar for iamthwee

I think he is too lazy to even try it himself. There is no way he will want to download the boost libraries being so lazy.

He just wants someone to code up the whole thing for him. He probably has no interest in c++.

I cannot do it myself, because I don't even know anything about (ok ok, i know basics) C++, because I'm a OBJECT programmer... clean C++ is for me ... like a miracle..

#iamthwee
The separator is a char

Member Avatar for iamthwee

So what's the point of this then?

Even in object programming I need function such as 'explode', to break commands...

having it in clean c++ would be useful in future...

making same command using object functions is not what is expected in the result

A lot of advices have been given to you already. What you are expecting here is someone to write the clean C++ code for the explode() function, which I don't think is going to happen. You last hope is to download the PHP source code and cut out the clean C++ implementation of the function. If not that, you are on your own.

I've downloaded PHP src. code, but I don't even know where to look for the func. implementation... there are so much files that I don't know what for...

Since I don't have PHP source code on my machine I can't help you in giving out the exact file name. But you can always open a file, and search for the word "explode". Half an hour of work should help you in finding the thing you are looking for.

So is this thread to post to if I want someone to code stuff for me? Cool.

Even if he had the PHP source code for that function it probably wouldn't do much good because it looks more like VB code than c or c++.

>>having it in clean c++ would be useful in future...
Of course you can write your own c++ function that simulates PHP's expode function pretty easily. $result is a c-style 2-dimensional character array, which is probably not what you want. In c++ the result array should be a vector.

Here is the start of a function

void explode( std::string str, std::vector<std::string>& array)
{
	std::string::size_type pos = str.find(' ');
	while( (pos = str.find(' ')) != std::string::npos)
	{
		// build array here

	}

}

Of course that function could return a vector, but that would be very very ineffienent because the program would have to duplicate the entire vector at least twice that I know of.

Provided the character is a delimter, here is a simple (and untested!!) piece of code which attempts to implement explode()

#include <string>
#include <vector>
#include <iostream>
#include <cstring>
using namespace std;

vector<string*>* explode(string str, char delimiter)
{
    vector<string*>* vec = new vector<string*>();
    char* result = NULL;
    const char* x = str.c_str();
    char* myString = (char *)(x);

    result = strtok(myString, &delimiter);
    while(result != NULL)
    {
        string* tmp = new string(result);
        vec->push_back(tmp);
        result = strtok(NULL, &delimiter);
    }
    return vec;
}

int main()
{
    vector<string*>* vec = explode("asdf+sdf+dfs+dfsdf+fd", '+');
    size_t size = vec->size();
    for(size_t i = 0; i < size; ++i)
        cout << *vec->at(i) << endl;

    // Don't forget to free memory
    for(size_t i = 0; i < size; ++i)
        delete(vec->at(i));
    delete(vec);
    
    cin.get();
    return 0;
}

Hmmm, mixing new and free ...

Oh!! Pardon me. Looks like I should have tested the code after all. Programming in different languages (java, C, C++) has started to kill me after all... ;-)

Making the changes right away. Thanks for noticing the blooper.

Member Avatar for iamthwee

Provided the character is a delimter, here is a simple (and untested!!) piece of code which attempts to implement explode()

#include <string>
#include <vector>
#include <iostream>
#include <cstring>
using namespace std;

vector<string*>* explode(string str, char delimiter)
{
    vector<string*>* vec = new vector<string*>();
    char* result = NULL;
    const char* x = str.c_str();
    char* myString = (char *)(x);

    result = strtok(myString, &delimiter);
    while(result != NULL)
    {
        string* tmp = new string(result);
        vec->push_back(tmp);
        result = strtok(NULL, &delimiter);
    }
    return vec;
}

int main()
{
    vector<string*>* vec = explode("asdf+sdf+dfs+dfsdf+fd", '+');
    size_t size = vec->size();
    for(size_t i = 0; i < size; ++i)
        cout << *vec->at(i) << endl;

    // Don't forget to free memory
    for(size_t i = 0; i < size; ++i)
        delete(vec->at(i));
    delete(vec);
    
    cin.get();
    return 0;
}

That's pretty unsightly and much of an overkill. Mixing c-style strings, and then implementing a delete for the std::vector which I'm sure already frees up memory in the way it is implemented?

At the very least [vectors], get around having to be resized constantly using new and delete.

here

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

using namespace std;

int main()
{
   string line = "hello world";

   char delim = ' ';

   vector <string> store;
   string token;
   istringstream iss ( line );

   while ( getline ( iss, token, delim ) )
   {
      store.push_back ( token );
   }

   cout << store[0] << endl;
   cout << store[1] << endl;
   cin.get();
}

The problem, as Ancient dragon mentioned is returning the vector, or rather the inefficiencies of it?

Your code won't work when the delimiters are more than one character. Also my program returns a pointer to a dynamically allocated vector, with the elements as string pointers so there are as such, no vector duplicates like AD said.Though its not the best solution one could come up with, its not that bad either considering was hacked in 10 minutes, for free and without bad programming practices... ;-)

Member Avatar for iamthwee

>delimiters are more than one character

But the op said his separators were only one char. In any case that doesn't matter. You could fix that easily.

>Though its not the best solution one could come up with, its not that bad either considering was hacked in 10 minutes.

LOL. Yeah well that's the c++, you can mix c and get away with it.

The OP is getting his work done with no effort from himself...Bah.

> But the op said his separators were only one char. In any case that
> doesn't matter. You could fix that easily.
Fixing your code which uses StringStreams for working with more than one characters would not be a trivial task. It would then involve getting knee deep into all the STL jargon.

> The OP is getting his work done with no effort from himself...Bah
:@ ;-)

Member Avatar for iamthwee

>Fixing your code which uses StringStreams

I never said I would use stringstreams. ;)

>Oh!! Pardon me. Looks like I should have tested the code after all.
I bet testing wouldn't have helped, g++ compiled and ran the program fine :P

string *getTokens(string s, string separator) {
   unsigned int tokens, pos;
   tokens = 1;
   string temp, *r = NULL;
   temp = s;
   while((pos = temp.find(separator)) != string::npos) {
      tokens += 1;
      temp.replace(0, pos + separator.length(), "");
   }
   r = new string[tokens + 1]; // add one extra element
   // and set last element to \0, so you can know when it ends
   r[tokens] = "#END_OF_TOKENS#";
   temp = s;
   // tokens now will be used as a counter to iterate through array
   tokens = 0;
   while((pos = temp.find(separator)) != string::npos) {
      r[tokens] = temp.substr(0, pos);
      temp.replace(0, pos + separator.length(), "");
      tokens++;
   }
   r[tokens] = temp.substr(0, pos);
   return r;
}

I found this online, can't remember where though.
enjoy!

/*
*	separates a string according to the delimiter passed and returns a vector<string>
*
*/
vector<string> explode (const string &str, const string &delimiter) 
{
    vector<string> arr;

    int strleng = str.length();
    int delleng = delimiter.length();
    if (delleng==0)
        return arr;//no change

    int i=0;
    int k=0;
    while( i<strleng ){
        int j=0;
        while (i+j<strleng && j<delleng && str[i+j]==delimiter[j])
            j++;
		if (j==delleng){	//found delimiter
            arr.push_back(  str.substr(k, i-k) );
            i+=delleng;
            k=i;
        }
        else{
            i++;
        }
    }
    arr.push_back(  str.substr(k, i-k) );
    return arr;
}

In C++ use getline :

#include <string>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;

std::vector<string> explode(const string& text, char delim){
 std::vector<string> res;
 string temp;
 stringstream ss(text);
 while(ss && getline(ss,temp,delim) ) res.push_back(temp);
 return res;
}

int main(){
 std::vector<string> vec;
 vec = explode("hello world",' ');
 cout << vec[0] << endl; //hello
 cout << vec[1] << endl; //world
}

I think you should write one. Check tokenization and then using basic C++ you can pack them in STL container
EDIT:
Ooops! I overlooked the other pages.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.