Hi everyone,

I was wondering if anyone could help - I'm trying to split up a char* that contains a string, something like "Stephen10:11:0002/07/2012Hi there"

I'm trying to split it up so it gets the position of the first * then the second, and stores whats between them in name and so on - so far I can get the positions of the *'s with

const char* msgStart = strchr (msg, '*');
const char* nameEnd  = strchr (msgStart+1, '*');

then assign

const char* name = msgStart+1;

but this puts the rest of the message in the name variable. I've tried using strncpy and memcpy to assign name;

char* nameBuffer = 0;
strncpy (nameBuffer, msg, nameEnd - msgStart);

But I jsut get a seg fault :S is there any way to split up a char* this way (I know I could just copy it to a std::string and do this alot quicker and easier, but I'm just trying to learn how to do it the hard way :))

Any help is much appreciated as always!!

Recommended Answers

All 5 Replies

you have to allocate memory (see malloc or new) for nameBuffere before you can copy something to it. Also, I don't see any * in the example you posted -- maybe because DaniWeb editor deleted them. If you want a star then you will have to escape it, such as \*

Do you check your return value from strchr for NULL? I ask because you search for '*' but you string does not appear to contain any *.

Also you do not appear to be assigning any memory to the pointer nameBuffer before you copy into it.

You need something like

char *nameBuffer = 0;
if (nameEnd != 0 && msgStart != 0)
{
    int size = nameEnd - msgStart;
    if (size > 0)
    {
        char *nameBuffer = new char[size+1];
        if (nameBuffer != 0)
        {
            strncpy (nameBuffer, msg, size);
        }
    }
}

The hard way is long (and hard) you need to check everything worked before continuing.

commented: yes :) +14

Yeah just realised now that all the '*' had been removed from the example -

*Stephen*10:11:00*02/07/2012*Hi there

Ah right, I thought you could just assign the buffer to hold the result to 0, since it was going to be pointing to an already existing char*... as you can tell, I'm still learning C/C++ lol :)

Here's a way of doing it using string, and C++ items:

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

int main(){
    string str="HEllo*world*hello.", split;
    vector<string> all;
    istringstream token(str);
    while (getline(token, split, '*')){
        all.push_back(split);
    }
    for (int i=0;i<(int)all.size();i++){
        cout<<all[i]<<endl;
    }
    return (0);
}

The all vector will contain all the substring between the given character, which is here the '*'.
But if you like to do it with chars, use Banfa's example.

Well, you can store pointers to the memory locations of the '*'s in your code but in order for them to work with other string functions and as you might want them to behave you have to terminate the string with a null character \0 (this is how strtok works). This might be a solution for you but I doubt it. I'd suggest using the facilities built into the C++ language to do what you want. For example:

#include <string>
#include <iostream>

int main () {
    const char * msg = "Stephen:10:11:000:2/07/2012:Hi There";
    std::string s(msg);
    std::cout << "Original: " << s << std::endl;
    size_t begin = 0, end = 0;
    while ((end = s.find(":", begin)) != std::string::npos) {
        std::cout << "Token: "
            << s.substr (begin, end - begin) << std::endl;
        begin = end + 1;
    }
    // Don't forget last token
    std::cout << "Token: "
            << s.substr (begin, s.size() - begin) << std::endl;
    return 0;
}

The above parses on teh ':' character, but it is an example you can build off of.

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.