?
Solved

Sorting a class vector and strtok???

Posted on 2004-08-22
4
Medium Priority
?
283 Views
Last Modified: 2010-04-01
Hi.

class CClass{
    private:
        string myStr;
    public:
        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:

    NUMBER*NUMBER*NUMBER

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?
0
Comment
Question by:Unimatrix_001
4 Comments
 
LVL 55

Accepted Solution

by:
Jaime Olivares earned 1120 total points
ID: 11864474
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, "*");

0
 
LVL 30

Assisted Solution

by:Axter
Axter earned 520 total points
ID: 11865162
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;

FYI:
>>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.
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 360 total points
ID: 11865166
>>    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);

or

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

part1=strtok(tmp, "*");

//...

delete [] tmp;


0
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 11865901
Points split :)
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question