bbs.chinaunix.net c/c++版trim函数实现讨论

首先有人提出了这个实现:

//用于判断是否是空格类字符的宏
#define isSpaces(ch) (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\b' || ch == '\f' || ch == '\n')

char *Trim(char *pszSource)
{
        //字符串首指针
        char *pszHead = pszSource;
        //用于保存最后非空格类字符的位置的指针
        char *pszLast = &pszSource[strlen(pszSource)-1];
        //查找最后非空格指针的位置
        while (isSpaces(*pszLast))
                --pszLast;
        *(++pszLast) = '\0';
        //查找首个非空格类字符的位置,以便左移字符串
        for ( ; (*pszHead != '\0') && (pszHead != pszLast); ++pszHead)
        {
                if (! isSpaces(*pszHead))
                {
                        strcpy(pszSource, pszHead);
                        break;
                }
        }

        return pszSource;
}


感觉调用strcpy次数过多。

我写了个:

char *Trim(char *psource)
{
                char *p1, *p2, *pfn;
                int fn = 0;

                pfn = p1 = p2 = psource;
                for(; *p1 != '\0'; p1++)
                {
                                if(!isSpace(*p1))
                                {
                                                p2 = p1;
                                                fn = 1;
                                }
                                else
                                {
                                                if(0 == fn)
                                                {
                                                                pfn++;
                                                }

                                }
                }
                *(p2 + 1) = '\0';
                if(psource != pfn)
                {
                                strcpy(psource, pfn);
                }
                return psource;
}

这里用了4个变量,一个循环,一个库函数(这个库函数用得有问题)。当时我觉得还不错了。后来一看flw写的:

void trim( char *str )
{
        char *copied, *tail = NULL;

        if ( str == NULL )
                return;

        for( copied = str; *str; str++ )
        {
                if ( *str != ' ' && *str != '\t' )
                {
                        *copied++ = *str;
                         tail = copied;
                }
                else
                {
                         if ( tail )
                                 *copied++ = *str;
                }
        }

        if ( tail )
             *tail = 0;
        else
             *copied = 0;

        return;
}

用了两个变量,一个循环,没有库函数。

//一个简单的宏,为了方便阅读
#define IS_SPACE(c) (c == ' ' || c == '\t')

char * fasttrim(char * str)
{
        char * start, * end = NULL;

        if(str == NULL)
                return NULL;

        //去掉头部的空格字符
        while( IS_SPACE(*str) ) str++;
        
        //start赋值,循环
        for(start = str; *str != '\0'; str++)
        {
                if ( IS_SPACE(*str) )
                {
                        //遇到非连续的第一个空格,上个位置就是可能的尾部
                        end = str++;

                        //去掉接下来连续的空格
                        while( IS_SPACE(*str) ) str++;

                        //没有到尾,还有其他的字符,上次记录的尾部无效
                        if(*str != '\0')
                                end = NULL; //invalid end
                }
        }

        if(end) *end = '\0';

        return start;
}

这个是另外一个人说的号称比flw实现要好的。

学习很多。

作者: hdc1112_cu   发布时间: 2010-11-03