C语言常用字符串函数的实现一

来源:互联网 发布:阿里云ecs是什么 编辑:程序博客网 时间:2024/04/28 14:36

1.strcpy:

函数的原型为char *strcpy(char *strDest, const char *strSrc);

strcpy的实现经常要注意的细节是:

(1)判断地址是否为空,个人感觉可以使用断言

(2)参数只有两个地址,没有拷贝的长度。拷贝到'\0‘时就会终止,要保证最终dest末尾是'\0'。

(3)要保证目标字串的长度足够,能够容纳原串的长度。

(4)因为拷贝是dest会移动,而最终要返回的是拷贝后字符串的起始地址,因此要先保存dest的地址,便于最终返回。

这里需要注意的地方函数的返回值就是行参的一个参数的值

char *strcpy(char * dest, const char * src)
{
    char *start = dest;
    while(*dest++ = *src++)
        ;
   
    return start;    // 等价于dest=p, return dest;
}

2.strncpy:

函数的原型为 char *strncpy(char *dest, const char *src, size_t n);

strncpy的功能和strcpy相似,只是它复制时多了一个终止条件。即是未遇到原串的'\0’,如果已经复制了n个字符(n为提供的参数长度),复制同样会终止。

方法一:

char * strncpy(char * dest, const char * source, size_t n)
{
        char *start = dest;

        while (n && (*dest++ = *source++))    /* copy string */
                n--;

        if (n)                            
                while (n--)
                        *dest++ = '\0';

        return  start;
}

方法二:

char* strncpy(char *dest, const char *src, size_t n)

{
               size_t i;

               for (i = 0 ; i < n && src[i] != '\0' ; i++)
                   dest[i] = src[i];

               for ( ; i < n ; i++)
                   dest[i] = '\0';

               return dest;
           }


3. memcpy

memcpy和strncpy有些类似,但也有本质的不同。

(1)strncpy只能复制字符串,但memcpy对类型没有要求。

(2)strncpy有两个终止条件,memcpy只有一个终止条件,那就是复制n个字节。(n是memcpy的第三个参数)

(3)要特别注意目的地址和源地址重合的问题,拷贝前要加以判断。

(4)实现这个函数时一般要把原来的指针类型转换成char*,这样每次移动都是一个字节。
地址重叠:

1.src在后,dst在前:自前向后拷贝

2.src在前,dst在后:自后向前拷贝

void *Memcpy(void *dst, const void *src, size_t size)
{
    char *psrc;
    char *pdst;

    if(NULL == dst || NULL == src)
    {
        return NULL;
    }

    if((src < dst) && (char *)src + size > (char *)dst)
    {
        psrc = (char *)src + size - 1; //这里 -1 需要注意一下
        pdst = (char *)dst + size - 1;
        while(size--)
        {
            *pdst-- = *psrc--;
        }
    }
    else
    {
        psrc = (char *)src;
        pdst = (char *)dst;
        while(size--)
        {
            *pdst++ = *psrc++;
        }
    }

    return dst;
}

4.strcat:

将参数 src 字符串拷贝到参数 dest 所指的字符串尾。在dest所指的空间追加拷贝,拷贝结束后,会自动在末尾添加 '\0'

第 一个参数 dest 要有足够的空间来容纳要拷贝的字符串。

char * strcat(char * dest, const char * src)
{
        char *start = dest;

        while (*dest)
                dest++;
        while ((*dest++ = *src++) != '\0')
                ;

        return start;
}

5.strcmp:

int strcmp(const char *str1,const char *str2)
{           
       int len = 0;
       assert((str1 != '\0') && (str2 != '\0'));
       while(*str1 && *str2 && (*str1==*str2))
       {
              str1++;
              str2++;
       }
       return *str1-*str2;
}

6.strlen:

size_t strlen(const char *s)

{
       size_t len = 0;

      while(*s++)

           len++;

     return len;

}

7.atoi:

atoi()函数的功能:将字符串转换成整型数;atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负号才开始做转换,而再遇到非数字或字符串时('\0')才结束转化,并将结果返回(返回转换后的整型数)。

int atoi(const char *nptr)
{
    int sign = 1;
    int val = 0;
    
    if (nptr == NULL)    //判断指针是否为空
        return -1;

    while (*nptr == '\0')  //跳过前面的空格
        nptr++;

    while (*nptr == '-' || *nptr == '+')
    {
        if (*nptr == '-')
            sign = -1;

        nptr++;
    }

    while (*nptr >= '1' && *nptr <= '9')
    {
        val = val *10 + *nptr++ - '0';
    }

    return val * sign;
}

0 0