zoukankan      html  css  js  c++  java
  • 字符串函数汇总

    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

     

  • 相关阅读:
    【转】linux常用命令
    【转】C++三大特性
    插入排序
    shixi
    【转】TCP协议
    【转】排序算法稳定性
    面筋BD
    斐波那契数列
    【面试题】D
    【学习笔记】OI模板整理
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4341411.html
Copyright © 2011-2022 走看看