我必须为一门课程做这个练习。
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}}
答案 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));
}
}