代码改变世界

字符串相关操作

2013-05-30 21:38  夜与周公  阅读(195)  评论(0编辑  收藏  举报

  接下来,总结一些常见的字符串操作算法,第一个介绍字符串拷贝操作。字符串拷贝算法比较著名的资料是林锐的<<高质量的C、C++>>,网上的很多文章都借鉴了里面有关字符串拷贝的论述。虽然字符串拷贝操作看起来很简单,但是如果仔细考虑,不禁觉得原来写代码真是件细工活,一个模板化的C++字符串拷贝代码如下:

char* str_copy(const char* pSource,  char* pDest)
{
    assert((pSource!=NULL) && (pDest!=NULL));
    char* address = pDest;
    while ((*pDest++ = *pSource++));
    return address;
}

  有关这段代码有以下几点思考(非算法上的):1)const 修饰 pSource目的是为了防止在程序中修改了pSource的值(如果修改pSource所指字符串内容,编译器将报错)。2)assert断言,程序严谨性的体现。3)返回address指针,让函数支持链式操作。用户在使用这个函数的时候需要保证pDest所指的空间要大于或者等于pSource所指空间的大小。

  

  第二个总结的字符操作是字符转换正整数,一个比较完整的字符串转换成整数的代码如下:

int atoi(const char* str)
{
    assert(str != NULL);
    int len = strlen(str);
    int sign = 1;
    int i = 0;
    int sum = 0;
    while( str[i] == ' ')
        ++i;
    if (str[i] == '-' || str[i] == '+')
        sign = str[i++] == '-' ? -1 : 1;

    for(;i != len ; i++)
    {
        if (str[i] >= '0' && str[i] <= '9')
        {
            sum = sum*10 + str[i]-'0';
        }
        else
            break;
    }
    return sign * sum;
}

  这个函数需要注意以下三点:1)字符串非空的断言,严谨性的体现;2)数字字符串前面可能存在着空格,因此需要吃掉空格;3)数字字符串前面也可能出现‘+’和‘-’,因此需要做特别的判断。这个函数主要考察的是编程的严谨性与细心。

  第三个总结的字符串操作是字符串比较函数,字符串比较函数相对简单:

int str_cmp(const char* s, const char* t)
{
    int ret = 0;
    assert(s != NULL && t !=NULL);
    while((*s && *t) && *s == *t)
    {
        s++;
        t++;
    }
    if ((*s - *t) > 0)
        ret = 1;
    else if ((*s - *t) < 0)
        ret = -1;
    return ret;
}

  第四个总结的是字符串的连接函数:

char* str_cat(char* dst, const char* src)
{
    assert(dst !=NULL && src != NULL);
    char* cp = dst;
    while (*cp) //find the end of dst
        cp++;
    while (*cp++ = *src++);
    return dst;
}

  此外,连接源字符串n个字符串函数:

char* str_ncat(char* dst, const char* src, size_t count)
{
    assert(dst !=NULL && src != NULL);
    char* cp = dst;
    while (*cp) //find the end of dst
        cp++;
    while (count--)
    {
        if (!(*cp++ = *src++))
return dst; } *cp = '\0'; return dst; }

  在使用这个函数的时候,用户需要保证dst所指的空间要大于或者等于合并的两个字符串长度之和,一种调用方式如下:

    char s[20] = "abcdef";
    char t[4] = "123";
    cout<<str_cat(s,t)<<endl;
    system("pause");
    return 0;