0

At the following first line of code I get this error: cannot convert ‘std::string’ to ‘char*’ for argument ‘1’ to ‘char* strtok(char*, const char*)’

void ToToken( ) {
    TokenLine.reserve(30);
    char * tmp;
    TokenLine[0]= strtok (Line," ");
    while(tmp!=NULL)
        for(int i=0;i<TokenLine.size();i++){
            TokenLine[i]= strtok(NULL," ");
            if(TokenLine[i]==NULL||TokenLine[i]==" ")
                TokenLine.erase(i);
            cout<<Token[i];
        }

}

Full code:

class CombatLine{

    string Line;
    bool combat;
    char LT[4];
    time_t rawtime;
    vector<string> TokenLine;

    CombatLine(){
        combat = false;
        }

    void SetLine(string S){
        Line="[Combat]  03:33:05 -Anthrax- Roshi heals -Anthrax- Roshi for 2630 points of damage.";
    }

    bool isLineCombat(){
        if(Line.substr(0,8)=="[Combat]")
            return true;
        else
            return false;
    }

    bool StrFound(string SubString){
        size_t tmp;
        tmp = Line.find(SubString);
        if(tmp!=string::npos)
            return true;
        else
            return false;
    }



    void SetLT(){
            LT[0]=Line.at(13);
            LT[1]=Line.at(14);
            LT[2]=Line.at(16);
            LT[3]=Line.at(17);
    }

    char ReturnLT(int Index){
        return LT[Index];
    }

    void SetType(){
        if (this->StrFound("(dodge)"))
            Event.SetType("dodge");
        if (this->StrFound(" (parry) "))
            Event.SetType("parry");
        if(this->StrFound("misses"))//because we know its not a parry or dodge if we made it this far
            Event.SetType("miss");
        if(this->StrFound(" strikes through "))
            Event.SetType("st");
        if(this->StrFound("(evaded)"))
            Event.SetType("evade");
        if(this->StrFound("crits"))
            Event.SetType("crit");
        if(this->StrFound("hits"))
            Event.SetType("hit");
        if(this->StrFound("glances"))
            Event.SetType("glance");
        else
            Event.SetType("not found");
    }

    void ToToken(){
        TokenLine.reserve(30);
        char * tmp;
        TokenLine[0]= strtok (Line," ");
        while(tmp!=NULL)
            for(int i=0;i<TokenLine.size();i++){
                TokenLine[i]= strtok(NULL," ");
                if(TokenLine[i]==NULL||TokenLine[i]==" ")
                    TokenLine.erase(i);
                cout<<Token[i];
            }

    }

    string ReturnType(){
        this->SetType();
        return Event.ReturnType();
    }

    void SetMinMax(){
        if(Event.ReturnType()=="miss"||Event.ReturnType()=="dodge"||Event.ReturnType()=="parry")
            Event.SetMinMax(0,0);
    }};

Am I passing the wrong type I string to strtok. I know I am playing with C-string and & C++ string without distinguishing them much.

Also is strtok a static method of String.h? What If I want to pass it another string to tokenize?

Thanks, Macaire Bell

casablanca
  • 69,683
  • 7
  • 133
  • 150
Malaken
  • 103
  • 1
  • 10

3 Answers3

3

strtok needs mutable C string, not std::string. To get a C string from std::string use c_str() method. However you should not pass it to strtok because it should not be changed. You'll need to make a copy of the string.

In order to create a copy possible way would be:

std::string strToTokenize;
char * tmpStr = new char[strToTokenize.size() + 1];
if (NULL == tmpStr) {...}
strcpy(tmpStr, strToTokenize.c_str());
// tokenize tmpStr
// ...
delete [] tmpStr;

or with std::vector:

std::string strToTokenize;
std::vector<char> tmpStr = strToTokenize; // don't have a compiler now, probably won't work
// tokenize char * cStrToTokenize = &(*strToTokenize.begin());
// ...
Drakosha
  • 11,925
  • 4
  • 39
  • 52
  • 1
    "You'll need to make a copy of the string." -> preferrably with a `std::vector` I suppose. – fredoverflow Nov 21 '10 at 18:42
  • @DrakoshaIf I understand you correctly: If I use c_str() it would change my string to a cstring? But since I am only copying it into a vector string as tokens I should create a local copy? – Malaken Nov 21 '10 at 18:43
  • 1
    @Malaken: `std::basic_string::c_str()` returns a pointer to a **constant** copy of the data held in the string. For most every STL implementation, that's going to be the same data that's actually held in the buffer inside the string, but that is by no means required. Basically, you cannot use the pointer returned by `c_str` to change the contents of the buffer at which the pointer points in any way (otherwise you have undefined behavior) – Billy ONeal Nov 21 '10 at 18:54
  • I consider `strtok()` just as an unnecessary complication in C++ code as the manual memory management in your first code snippet. Streams are _much_ easier to use. – sbi Nov 21 '10 at 19:03
  • Where would be a good place to read up on streams. I am fairly ignorant about streams, and completely ignorant about string streams. – Malaken Nov 21 '10 at 19:19
0

Also is strtok a static method of String.h? What If I want to pass it another string to tokenize?

strtok() is a beast from the C Standard library, which C++ got by inheritance. From a C++ POV, it's unsafe and should be avoided. The way to tokenize a whitespace-separated string in C++ is to use string streams. Roughly:

std::istringstream iss(Line);
std::string token;
while(iss >> token) // fails on error and EOF
  process(token);
if(!iss.eof()) // failed on error
  throw "Dude, you need error management!";
sbi
  • 219,715
  • 46
  • 258
  • 445
  • where is a good place to read up on this, because half of the code look unfamiliar – Malaken Nov 21 '10 at 19:04
  • @Malaken: Any [good introductory book](http://stackoverflow.com/questions/388242) will cover this. – sbi Nov 21 '10 at 20:15
-3

Change

TokenLine[0]= strtok (Line," ");

to

TokenLine[0]= strtok (Line.c_str()," ");
pr1268
  • 1,176
  • 3
  • 9
  • 16
  • look my answer above, it's not OK to do it. – Drakosha Nov 21 '10 at 18:39
  • This is wrong: c_str() returns a const char *. If this compiles (due to a compiler allowing to ignore that fact), it is unsafe (UB to be exact) since std::string does not expect the returned character array to be modified. – mmmmmmmm Nov 21 '10 at 18:44
  • I was just gonna comment on my new compiler error error: invalid conversion from ‘const char*’ to ‘char*’ – Malaken Nov 21 '10 at 18:48
  • I stand corrected. Blame it on my lack of coffee or whatever. Drakosha's and my answers overlapped but he/she's correct. – pr1268 Nov 21 '10 at 18:50