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

Posted by richard爱闹 - 7月 21 2014
如需转载,请注明: 本文来自 Richard