使用C ++中的strtok拆分char *

时间:2014-06-05 20:57:49

标签: c++ split char strtok

我必须为一门课程做这个练习。

class Cadena{
protected:
char * s;
bool I;
}

char * s具有以下样式:“text1:text2::text3:”我需要通过在Lista<Cadena>时拆分char *来生成列表(:)每当我收到::时,我必须在我生成的列表中添加“@EMPTY@”,如果以:结尾,我需要在“@EMPTY@”添加dividirTupla我的清单结束。

现在我有这两种方法,split工作得很好并且做了我需要的一切但是你可以看到它不是“最好的”代码,而char *完成了大部分工作我需要但我无法意识到::我已经“@EMPTY@” Lista<Cadena>* Cadena::dividirTupla(){ if(s!=NULL){ Lista<Cadena> *ret=new ListaImp<Cadena>(); int ppio=0; int fin=0; //Go over the char * in order to find the : for(int i=0; i<strlen(s); i++){ if(s[i]==':'){ //If there is a :: if(ppio==fin){ ret->AgregarFin("@EMPTY@"); }else{ //If we find a : we add the substring to our list string a=((string)s).substr(ppio,fin-ppio); char * dato = new char[a.length() + 1]; strcpy(dato,a.c_str()); //It adds the char * to the list ret->AgregarFin(dato); delete dato; } fin++; ppio=fin; }else{ fin++; } } //Add the last text if(ppio<strlen(s)){ string a=((string)s).substr(ppio,strlen(s)); char * dato = new char[a.length() + 1]; strcpy(dato,a.c_str()); ret->AgregarFin(dato); delete dato; } //If it ends in : add the @EMPTY@ if(s[strlen(s)-1]==':'){ ret->AgregarFin("@EMPTY@"); } cout<<*ret; return ret; }else{ return NULL; } } Lista<Cadena>* Cadena::split(){ if(s!=NULL){ char * aux=strtok(s,":"); Lista<Cadena> *ret=new ListaImp<Cadena>(); while(aux != NULL){ ret->AgregarFin(aux); aux= strtok(NULL, ":"); } return ret; }else{ return NULL; } } ,因此我可以在正确的位置添加{{1}}到我的列表中。

我有什么办法吗?所以第二种方法可以工作,而不是使用第一种方法,而不是使用第一种方法。

{{1}}

1 个答案:

答案 0 :(得分:0)

只是为了证明保罗是错的;)你可以使用strstr而不是吗?

如果没有,我只是重写strtok,我自己返回一个结构,因此可以在调用代码时区分NULL错误情况和0长度匹配。

使用strstr,大致相似的东西(虽然会出现像&#34;:xx:xx&#34;你要修复的行)...

扫描分隔符&#34;:&#34;,当发现重新扫描重复的&#34; ::&#34; 如果我们有重复,请复制出EMPTY标记,然后再次查看&#34; ::&#34;

copyFromUntil,应该从第一个到第二个char *指针保存令牌。

strstr - 找到一个子字符串,请参阅http://linux.die.net/man/3/strstr

//
// Handle stuff like "", "xxx", "xx::xx:::xx:xx::::xxx" and "xx::xx:::xx:xx::::xxx:"
//
// first find a ":", then check if it's "::"
char *delim, *repeateddelim;
while ((delim  = strstr( s, ":") != NULL) {

    // Process from s..delim
    copyFromUntil( s, delim);

    // Scan for repeated delimiter's eg) : in "xx::xx:::xx:xx::::xxx"
    while (delim == (repeateddelim = strstr( delim, "::")) {

        // Insert the empty delimitter marker
        copyFromUntil( EMPTY_STR, EMPTY_END);

        /* Resume scan from 2nd ':'
        s = delim = repeateddelim;
    }
    // At a single ":" now, move past, saving delim pos
    lastdelim = delim;
    s= delim+1;
}
// From start of line or last ":" to EOL
if (s) {
    if (strlen(s) == 0 && (s == lastdelim+1) {    //  one past a delimiter?
        copyFromUntil( EMPTY_STR, EMPTY_END);
    } else {
        copyFromUntil( s, s + strlen(s));
    }
}