C++ 使用C+中的strtok拆分字符*+;

C++ 使用C+中的strtok拆分字符*+;,c++,split,char,strtok,C++,Split,Char,Strtok,我必须为一门课做这个练习 class Cadena{ protected: char * s; bool I; } char*s具有以下样式:“text1:text2::text3:我需要通过在有:时拆分char*来生成一个列表(Lista),每次我得到一个:,我必须添加一个“@EMPTY@”到我正在生成的列表中,如果列表以结尾:我需要在列表末尾添加一个“@EMPTY@ 现在我有了这两种方法,dividirTupla工作得很好,做了我需要的一切,但正如你所看到的,它不是有史以来“最好”的代码,

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

class Cadena{
protected:
char * s;
bool I;
}
char*s
具有以下样式:
“text1:text2::text3:
我需要通过在有
时拆分
char*
来生成一个列表(
Lista
),每次我得到一个
,我必须添加一个
“@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;
        }
    }
Lista*Cadena::dividirTupla(){
如果(s!=NULL){
Lista*ret=new ListaImp();
int-ppio=0;
int-fin=0;
//检查字符*以查找:
对于(int i=0;iAgregarFin(“@EMPTY”);
}否则{
//如果我们找到a:我们将子字符串添加到列表中
字符串a=((字符串)s).substr(ppio,fin ppio);
char*dato=新字符[a.长度()+1];
strcpy(dato,a.c_str());
//它将字符*添加到列表中
ret->AgregarFin(达托);
删除dato;
}
fin++;
ppio=fin;
}否则{
fin++;
}
}
//添加最后一个文本
if(ppioAgregarFin,dato);
删除dato;
}
//如果以结尾:添加@EMPTY@
如果(s[strlen(s)-1]==':'){
ret->AgregarFin(“@EMPTY”);
}
你能用、
strstr
来代替吗

如果不是,我只需要重新编写strtok,返回一个结构,这样就可以在调用代码中区分空错误情况和0长度匹配

对于strstr,大致类似于(尽管会有“:xx:xx”行之类的bug需要修复)

扫描分隔符“:”,找到时重新扫描重复的分隔符“:: 如果有重复,请复制空标记,然后再次查找“:”

CopyFromTill应将令牌从第一个字符保存到第二个字符*指针

strstr-定位子字符串请参见


真是噩梦。如果你被给予同样的要求,但是被告知使用C++(使用标准库)来做这件事,这仍然是一个很好的练习。相反,你被告知用这种容易出错的低逻辑来做这件事。你不妨在C中做这个。真是太遗憾了。看起来他们在C中做……(注:C++不是)。“C,带列表”!哦,好的,我知道了。我更改了C的标记。谢谢!不,代码是C++,但是它不使用C++提供的任何设备。它基本上是“C”,其中有几个C++关键字被抛出(如<代码>新< /COD>和<代码>删除< /代码>)。,加上它有一个未知的
Lista
类型。有一件事,请在整个代码中使用
std::string
。不要仅仅为了它而开始使用
char*new[]
。你正在使用
std::string
,然后出于某种奇怪的原因,你马上切换回使用
new char[]<代码> >为什么?好的。我读了你的要求。它只是冒号分隔的字符串解析器。如果需要,没有标记的话,你可以做的是用字符串来标记字符串,并用Word <代码> @空@ < /CUTE重新生成一个新的字符串。有很多更好的方法使用诚实C++,而不是C类。如果你对C++的答案感兴趣,请这样说。否则,我认为没有人会像现在这样费力地阅读您的代码。谢谢Rob,我会尝试这个或类似的方法,看看它是否有效。如果允许您通过2次,那么您可以在上使用strstrstr,将字符串从xxx:xx::xx重建到xxx:xx:@EMPTY@:xx,然后使用您已经编写的strok方法。仍然留下:xx:但要处理的案件。
//
// 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));
    }
}