• 字符串函数汇总


    1 strcpy

    为什么strcpy要有返回值?

     返回strDest的原始值使函数能够支持链式表达式,增加了函数的“附加值”。同样功能的函数,如果能合理地提高的可用性,自然就更加理想。
        链式表达式的形式如:
            int iLength=strlen(strcpy(strA,strB));
        又如:
            char * strA=strcpy(new char[10],strB);
        返回strSrc的原始值是错误的。其一,源字符串肯定是已知的,返回它没有意义。其二,不能支持形如第二例的表达式。其三,为了保护源字符串,形参用const限定strSrc所指的内容,把const char *作为char *返回,类型不符,编译报错。

    strcpy的原型为extern char* strcpy(char *dest,const char *src);它包含在头文件string.h中,它的返回值指向dest的指针,其功能是把src所指由NULL结束的字符串复制到dest所指的数组中。值得注意的是,src和dest所指内存区域不可以重叠,且dest必须有足够的空间来容纳src的字符串,src字符串尾的字符串结束标志''也会被复制过去。

    char* strcpy(char *strDes, char *strSrc)
    {
        if (strDes == strSrc)                       //判断是否相等
            return strDes;
        assert(strDes != NULL && strSrc != NULL);   //判空
        char *des = strDes;                         //保存strDes基址
        while ((*des++ = *strSrc++) != '')       //判断结束
            ;
        return strDes;
    }

    字符串拷贝函数需要考虑到以下几点:

    1. 原字符串与目标字符串内存重叠
    2. 对原字符串和目标字符串进行NULL检查
    3. 保存目标字符串strDes基址
    4. 赋值过程中递增以及判空

    2 strncpy

    char* strncpy(char *strDes, char *strSrc, size_t n)
    {
        if (strDes == strSrc)
            return strDes;
        assert(n > 0 && strDes != NULL && strSrc != NULL);
        char *des = strDes;
        while ((*des++ = *strSrc++) != '' && n-- > 0)
            ;
        if (*(--des) != '')
            *des = '';
        return strDes;
    }

    3 memcpy

    注意:memcpy memmove区别和实现

    memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。

    但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。

    memmove的处理措施:

    (1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝

    (2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝

    (3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝

    memcpy是C语言中的内存复制函数,它的函数原型为void *memcpy(void *dest,const void *src,size_t n).它的目的是将src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内,函数返回指向dest的指针。需要注意的是,src和dest所指内存区域不能重叠,同时,与strcpy相比,memcpy遇到''不结束,而是一定要复制完n个字节。而且如果目标数组dest本身已有数据,执行memcpy()之后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到要追加数据的地址。

    memmove()函数用来做内存复制,可以拿他来复制任何数据类型的对象,可以指定复制的数据长度。

    void *memmove(void *dest,void *src,size_t count)
    {
        char *pdest=(char*)dest;
        const char *psrc=(const char*)src;
        if(pdest>psrc&&pdest<(pstr+count)) //有重叠区域
        {
            for(size_t i=count-1;i>=0;--i)
                pdest[i]=psrc[i];
        }
        else
        {
            for(size_t i=0;i<count;i++)
            {
                pdest[i]=psrc[i];
            }
        }
        return dest;
    }
    

    memcpy实现:

    void* memcpy(void* dest, void* source, size_t count)
    
          {
    
               void* ret = dest;
    
              //copy from lower address to higher address
    
              while (count--)
    
                      *dest++ = *source++;
    
    
               return ret;
    
          }

     4 实现字符串转换为整型(atoi)

    注意:a 空格 b 正负号 c 是否为数字 d 是否会溢出

        int atoi(string str) {
            if(str.empty())
                return 0;
            int i=0;
            while(str[i]==' ') i++;
            int flag=1;
            if(str[i]=='-')
            {
                flag=-1;
                i++;
            }
            else if(str[i]=='+')
                i++;
            long long res=0;
            while(str[i]!=''&&isdigit(str[i]))
            {
                res=res*10+(int)(str[i]-'0');
                if(flag==1&&res>INT_MAX)
                    return INT_MAX;
                else if(flag==-1&&-res<INT_MIN)
                    return INT_MIN;
                i++;
            }
            return flag*res;
        }

    5 实现itoa

    注意:a 正负号 b 结尾添加''

    char *itoa(int num)
    {
        char str[1024];
        int sign=num,i=0,j=0;
        char temp[11];
        if(sign<0)
        {
            num=-num;
        }
        while(num>0)
        {
            temp[i]=num%10+'0';
            num/=10;
            i++;
        }
        if(sign<0)
        {
            temp[i++]='-';
        }
        temp[i]='';
        i--;
        while(i>=0)
        {
            str[j]=temp[i];
            i--;
            j++;
        }
        str[j]='';
        return str;
    }

     6 不使用任何变量,如何实现计算字符串长度的函数strlen()

    使用变量时,strlen的实现

    int strlen(const char *str)
    {
        int len=0;
        if(str==NULL)
            return len;
        while(*str++!='') len++;
        return len;
    }
    

    不使用变量,实现:

    int strlen(const char *s)
    {
        if(*s=='')
            return 0;
        else
            return 1+strlen(++s);
    }
    

     7 strchr实现

    char *strchr(const char *str,int c)
    {
        assert(str!=NULL);
        while(*str!=''&&*str!=(char)c) ++str;
        if(*str=='')
            return NULL;
        return str;
    }

    8 strcmp实现

    int strcmp(const char *s,const char *t)
    {
        assert(s!=NULL&&t!=NULL);
        while(*s!=''&&*t!=''&&*s==*t)
        {
            ++s;
            ++t;
        }
        return (*s-*t);
    }

    9 strcat实现

    char *strcat(char *strDes,const char *strSrc)
    {
        assert(strDes!=NULL&&strSrc!=NULL);
        char *address=strDes;
        while(*strDes!='')
            ++strDes;
         while((*strDes++=*strSrc++)!='')
            ;
         return address;
    }

    更多参考:http://blog.csdn.net/v_JULY_v/article/details/6417600

     

  • 相关阅读:
    51nod 1087 1 10 100 1000(找规律+递推+stl)
    51nod 1082 与7无关的数 (打表预处理)
    51 nod 1080 两个数的平方和
    1015 水仙花数(水题)
    51 nod 1003 阶乘后面0的数量
    51nod 1002 数塔取数问题
    51 nod 1001 数组中和等于K的数对
    51 nod 1081 子段求和
    51nod 1134 最长递增子序列 (O(nlogn)算法)
    51nod 1174 区间中最大的数(RMQ)
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4341411.html
Copyright © 2020-2023  润新知