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