2010-11-21 7 views
0

À la première ligne de code suivante, j'obtiens cette erreur : impossible de convertir 'std :: string' en 'char *' pour l'argument '1' en 'char * strtok (char *, const char *) »Tokenizing String C++ compilateur/erreur logique

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

} 

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

Suis-je passer la mauvaise chaîne de type I à strtok. Je sais que je joue avec C-string et & chaîne C++ sans les distinguer beaucoup.

Est également strtok une méthode statique de String.h? Que faire si je veux passer une autre chaîne à tokenize?

Merci, Macaire de Bell

Répondre

3

strtok a besoin chaîne mutable C, pas std::string. Pour obtenir une chaîne C à partir de std::string, utilisez la méthode c_str(). Cependant, vous devez le passer à strtok car il ne doit pas être modifié. Vous devrez faire une copie de la chaîne.

Afin de créer une copie façon possible serait:

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

ou avec 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()); 
// ... 
+1

"Vous devrez faire une copie de la chaîne." -> de préférence avec un 'std :: vector ' je suppose. – fredoverflow

+0

@Drakosha Si je vous comprends bien: Si j'utilise c_str() cela changerait ma chaîne en cstring? Mais puisque je le copie seulement dans une chaîne de vecteur comme des jetons je devrais créer une copie locale? – Malaken

+1

@Malaken: 'std :: basic_string :: c_str()' retourne un pointeur sur une copie ** constante ** des données contenues dans la chaîne. Pour la plupart des implémentations STL, ce sont les mêmes données qui sont réellement conservées dans le tampon à l'intérieur de la chaîne, mais cela n'est en aucun cas nécessaire. Fondamentalement, vous ne pouvez pas utiliser le pointeur retourné par 'c_str' pour changer le contenu du tampon sur lequel pointe le pointeur (sinon vous avez un comportement indéfini) –

-3

changement

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

à

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

regardez ma réponse ci-dessus, ce n'est pas OK de le faire. – Drakosha

+0

C'est faux: c_str() retourne un const const *.Si cela compile (en raison d'un compilateur permettant d'ignorer ce fait), il est dangereux (UB pour être exact) puisque std :: string ne s'attend pas à ce que le tableau de caractères retourné soit modifié. – mmmmmmmm

+0

Je voulais simplement commenter mon erreur de compilation erreur: conversion invalide de 'const char *' en 'char *' – Malaken

0

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

strtok() est une bête de la C bibliothèque standard, qui a obtenu par héritage C++. A partir d'un POV C++, c'est dangereux et devrait être évité. La façon de marquer une chaîne séparée par des espaces dans C++ consiste à utiliser des flux de chaîne. Approximativement:

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

où est un bon endroit pour lire à ce sujet, parce que la moitié du code semble peu familier – Malaken

+0

@Malaken: Tout [bon livre d'introduction] (http://stackoverflow.com/questions/388242) couvrira cela. – sbi