2010-11-21 59 views
0

在下面的第一行代码中,我得到这个 错误:无法将参数'1'的'std :: string'转换为'char *'到'char * strtok(char *为const char *)”Tokenizing String C++编译器/逻辑错误

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]; 
     } 

} 

全码:

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); 
    }}; 

我是传递了错误的类型我字符串函数strtok。我知道我在玩C字符串和C++字符串,但没有太多区别。

也是strtok一个String.h的静态方法吗?如果我想通过它另一个字符串来标记?

感谢,MACAIRE贝尔

回答

3

strtok需要可变的C字符串,不std::string。要从std::string获得C字符串,请使用c_str()方法。但是,您应该而不是将它传递给strtok,因为它不应该更改。你需要制作一个字符串的副本。

为了创建一个副本,可能的方式是:

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

或性病::向量:

std::string strToTokenize; 
std::vector<char> tmpStr = strToTokenize; // don't have a compiler now, probably won't work 
// tokenize char * cStrToTokenize = &(*strToTokenize.begin()); 
// ... 
+1

“你需要复制一个字符串。” - >最好用'std :: vector '我想。 – fredoverflow 2010-11-21 18:42:49

+0

@Drakosha如果我理解正确: 如果我使用c_str()它会将我的字符串更改为一个cstring? 但是,因为我只是将它复制到一个矢量字符串作为令牌,我应该创建一个本地副本? – Malaken 2010-11-21 18:43:19

+1

@Malaken:'std :: basic_string :: c_str()'返回一个指向字符串中保存的数据的**常量**副本的指针。对于大多数STL实现来说,这将与字符串内缓冲区中实际保存的数据相同,但这绝不是必需的。基本上,你不能使用'c_str'返回的指针以任何方式改变指针所指向的缓冲区的内容(否则你有未定义的行为) – 2010-11-21 18:54:25

-3

变化

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

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

看上面我的答案,这是不行的。 – Drakosha 2010-11-21 18:39:23

+0

这是错误的:c_str()返回一个const char *。如果编译(由于编译器允许忽略该事实),它是不安全的(UB是准确的),因为std :: string不希望返回的字符数组被修改。 – mmmmmmmm 2010-11-21 18:44:53

+0

我只是要评论我的新编译器错误 错误:从'const char *'无效转换为'char *' – Malaken 2010-11-21 18:48:50

0

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

strtok()是一个来自的野兽C标准库,C++通过继承获得。从C++ POV看,这是不安全的,应该避免。在C++中标记一个空白分隔的字符串的方法是使用字符串流。粗略地说:

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!"; 
+0

在哪里是阅读这个好地方,因为一半的代码看起来不熟悉 – Malaken 2010-11-21 19:04:17

+0

@Malaken:任何[良好的介绍性书](http://stackoverflow.com/questions/388242)将涵盖这一点。 – sbi 2010-11-21 20:15:44