trim variant c cpp string
实现trim的variant,将多个空格变为1个。但是逻辑似乎对我来说短时间不简单啊。
我开始尝试的是C++字符串,一个istringstream搞定,但是其实也会有问题,后来发现要试试C的,不然有点像调用了一个库或者class的感觉。
char * trim(char* str)
{
int i=0;
int len=strlen(str),startpos;
char* a=new char[len+1];
int offset=0;
while(i<len)
{
startpos=i;
while(i<len&&str[i]!=' ')
i++;
if(i==len) break;
for(j=startpos;j<i;j++)
{
a[offset]=str[j];
offset++;
}
a[offset]=' ';
offset++;
while(i<len&&str[i]==' ')
i++;
}
a[offset]='\0';
strcpy(str,a);
delete[] a;
return str;
}
上面代码有点问题的,break早了,最后一个非空格的串还没copy过去,另外改成strncpy,提高可读性
char * trim_new(char* str)
{
int i=0,j;
int len=strlen(str),startpos;
char* a=new char[len+1];
int offset=0;
while(i<len)
{
startpos=i;
while(i<len&&str[i]!=' ')
i++;
strncpy(a+offset,str+startpos,i-startpos);
/*
for(j=startpos;j<i;j++)
{
a[offset]=str[j];
offset++;
}
*/
offset+=i-startpos;
if(i==len) break;
a[offset]=' ';
offset++;
while(i<len&&str[i]==' ')
i++;
}
a[offset]='\0';
strcpy(str,a);
delete[] a;
return str;
}
我已开始犯了一个严重,但是我一直因为没弄清楚字符数组,字符串的区别导致的,上一篇总结好了。我用char a[]=”” 最后return a, 发现其实返回之后这块地址因为是栈的被销毁了,所以挂了。。。。
于是改成堆,但是又要释放空间这样比较好,然后只能拷贝回str,而且逻辑似乎不好,好不如直接在源串上改。
于是有了下面两个指针的代码,i指向当前处理好的字符串后一个位置,j指向后面待处理的字符串,记得开始记录startpos,所以是[startpos,j) copy回 i开始的位置,里面有个地方容易忽视,就是如果最后面是非空格的一串,后面要避免被赋上空格,或者直接break返回
也可以的,不break也可以因为后面condition控制好了越界的情况。
char *trim(char* str)
{
int len=strlen(str);
int i=0,j=0,startpos;
while(j<len)
{
startpos=j;
while(j<len && str[j]!=' ')
j++;
strncpy(str+i,str+startpos, j-startpos);
i+=j-startpos;
if(j<len)//no more space add
{
str[i]=' ';
i++;
}
while(j<len && str[j]==' ')
j++;
}
str[i]='\0';
return str;
}
另外还有一个简单的C++ istringstream版的,但是好像有问题,例如开头一串空格的一个空格就丢了,因为里面封装了太多了,改起来不易。。。
char *trim(char *str)
{
string strcpp=str;
istringstream istr(str);
istr>>outstr;
while(istr>>split)
outstr+=" "+split;
strcpy(str,outstr.c_str());
return str;
}
今天再次写这个程设题,总结了一些经验,如果先找非空格,后找空格似乎控制麻烦,就换成先找空格后找费空格,代码很好控制,而且如果能一个一个copy就尽量这种,不要通过计算坐标
使得代码还麻烦,尽量不要把break出去的处理,在里面各个分支处理好就可以了。
更简洁的就地双指针遍历版本如下:
char* trimspace(char* cstr)
{
int cstrlen=strlen(cstr);
int i=0,j=0,start;
while(i<cstrlen)
{
//start=i;
bool hasspace=false;
while(i<cstrlen && cstr[i]==' ')
i++, hasspace=true;
if(hasspace==true)
cstr[j]=' ',j++;
if(i==cstrlen)
{
cstr[j]='\0';
break;
}
while(i<cstrlen&& cstr[i]!=' ')
cstr[j++]=cstr[i++];
if(i==cstrlen)
cstr[j]='\0';
}
return cstr;
}