• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 290
  • Last Modified:

Sorting a class vector and strtok???


class CClass{
        string myStr;
        void setMyStr(string a);
        string getMyString();

void someMethod(){
    sort(myCClass.begin(), myCClass.end(), someSortMethod);

void someSortMethod(CClass a, CClass b){
    string fst=a.getMyString();
    string snd=b.getMyString();

    char *part1;
    char *part2;
    char *part3;

    part1=strtok((char*)fst.c_str(), "*");
    part2=strtok(NULL, "*");
    part3=strtok(NULL, "*");

myStr is in the format:


However, when this line is done:

    part1=strtok((char*)fst.c_str(), "*");

then it modifies the fst.myStr variable, making the further strtok calls crash. How can I keep this from happening?
3 Solutions
Jaime OlivaresSoftware ArchitectCommented:
First of all, part1,2,3 are assigned but not used.

when you assign one string to the other, a copy is not created, just a reference to the first, like a Windows File Shorcut.
So, strtok will affect fst too. Strtok is not well suited to handle a STL string buffer.
To avoid this, you can create a copy in a standard C buffer, and apply strtok to it, something like:

char fst[234];  // any buffer size
strcpy(fst, a.c_str(), a.size());

Then you can apply strtok without worrying:
part1=strtok(fst, "*");
part2=strtok(NULL, "*");
part3=strtok(NULL, "*");

I recommend using C++ approach since you're using C++ STL objects.

Example code:

int main(int argc, char* argv[])
      std::string Data = "NUMBER*NUMBER*NUMBER*"; //Added extra asteric for simplicity
      int part1 = Data.find('*');
      int part2 = Data.find('*', part1+1);
      int part3 = Data.find('*', part2+1);

      cout << Data.substr(0, part1) << endl;
      cout << Data.substr(part1+1, (part2-part1)-1) << endl;
      cout << Data.substr(part2+1, (part3-part2)-1) << endl;

>>when you assign one string to the other, a copy is not created, just a reference to the first
This is called reference counting, and almost all implementations use this approach, but according to the C++ standard, they don't have to.

You should never cast an std::string buffer to a non-constant C style string.
There are too many things that can go wrong.
>>    part1=strtok((char*)fst.c_str(), "*");

You have noticed that 'c_str()' returns a 'const char*'?

As jaime_olivares already suggested, store your data in a different place for tokenizing it. But to overcome the inherent danger of a buffer overflow with a fixed size array, I'd suggest to either use

char* tmp = strdup ( fst.c_str());

part1=strtok(tmp, "*");


free ( tmp);


char* tmp = new char [ fst.c_str()];
strcpy(fst, a.c_str(), a.size());

part1=strtok(tmp, "*");


delete [] tmp;

Unimatrix_001Author Commented:
Points split :)
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now