【发布时间】:2014-06-05 20:57:49
【问题描述】:
我必须为一门课程做这个练习。
class Cadena{
protected:
char * s;
bool I;
}
char * s 具有以下样式:“text1:text2::text3:” 我需要通过拆分 char * 来生成一个列表 (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;
}
}
【问题讨论】:
-
真是一场噩梦。您知道,如果您有相同的要求,但被告知使用 C++(使用标准库)执行此操作,这仍然是一个很好的练习。相反,您会被告知使用这种容易出错的低级逻辑来执行此操作。您不妨在“C”中执行此操作。真可惜。
-
看起来他们是用 C 来做的......(注意:C++ 不是“C with lists”!)
-
哦,好的,我明白了。我更改了 C 的标签。谢谢!
-
不,代码是 C++,但它不使用 C++ 必须提供的任何功能。它基本上是带有一些 C++ 关键字的“C”(例如
new和delete),而且它还有这个未知的Lista类型。一件事,请在整个代码中使用std::string。不要为了它而开始使用char* new[]。您正在使用std::string,然后出于某种奇怪的原因,您立即切换回使用new char[]。为什么? -
好的。我读了你的要求。它只是一个以冒号分隔的字符串解析器。您需要做的就是对字符串进行标记,如果没有找到标记,则使用单词
@EMPTY@重建一个新字符串。有很多更好的方法可以使用诚实的 C++,而不是 C 和类。如果您对面向 C++ 的答案感兴趣,请说出来。否则,我认为没有人会像现在这样尝试浏览您的代码。