常见的几个库函数

strcpy()

原型声明:char strcpy(char dest, const char *src); 
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间 
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 
返回指向dest的指针。

#include <assert.h>

char* strcpy(char* dest, const char* src) //point1: 源字符串不变,需要加const保证
{
        if(src == dest)  //重叠
        {
                return src;
        }
        assert(dest != NULL && src != NULL); //point2: 保证指针有效
        char* temp = dest;  //point3: 下面涉及到指针的移动,而我们需要返回dest的头指针。所以dest保留,用temp来移动
        while((*temp++ = *src++) != '\0')

        /*point4: 末尾的'\0'也要复制过来
         *上面先执行 *temp++ = *src++ ,再判断*src 是否等于 '\0'  
         *所以保证了 '\0' 先复制后判断
         */
         
         return dest;  //piont5: 返回dest头指针,支持链式表达式
}

链式的例子:

int length = strlen(strcpy(strA,strB));

strncpy()

strcpy()是一个高危函数,因为没有指定复制的大小,当dest的空间比src小时,就会出错,而我们没法进行控制。于是有了比较安全的strncpy():

把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。

#include <assert.h>

char* strncpy(char* dest, const char* src, unsigned int n)
{
        assert(dest != NULL && src!= NULL);
        char* temp = dest;
        while(n-->0 && (*temp++ = *src++)!= '\0')
    
        /*上面语句两种终止情况:
         *1、n=0,此时下面的语句不执行,如果未到达src末尾
         *不会自动在dest末尾添加 '\0' 的,所以需要使用者自己添加
         *2、n>0 但是src已经到达末尾,那么执行下面语句,将
         *dest填充 '\0' 达到长度n
         */
         while(n-->0)
                 *temp = '\0';
         return dest;
}

strcmp()

比较两个字符串 
设这两个字符串为str1,str2, 
若str1==str2,则返回零; 
若str1>str2,则返回正数; 
若str1<str2, 返回负数。

#include <assert.h>

int strcmp(const char* str1, const char* str2)
{
        assert(dest != NULL && src!= NULL);
        /*不可用while(*str1++ == *str2++) 来比较,当不相等时仍会执行一次++,
         *return 返回的比价值实际上是下一个字符。应将++放到循环体中
       */
      while(*str1 && *str2 && *str1 == *str2)
      {
              str1++;
              str2++;
      }
      return *str1 - *str2;
      /* 若相等,则*str1 - *str2 = '\0' - '\0' = 0;
     * 否则,*str1 - *str2 != 0;
     * 因为前面的位都相等,所以只需要比较当前位来确定返回值
     */
}

strcat()

把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)。

#include <assert.h>

char* strcat(char *dest, const char* src)
{
        assert(dest != NULL && src != NULL);
        char* temp = dest;
        while(*temp != '\0)   //不要  (*temp++ != '\0')
        {
                temp++;
        }
        while((*temp = *src) != '\0')
        {
                temp ++;
                src++;
        }
        return dest;
}

strlen()

功能:计算给定字符串的(unsigned int型)长度,不包括’\0’在内 
说明:返回s的长度,不包括结束符NULL。

#include <assert.h>

unsigned int strlen(const char* s)
{
        assert(s != NULL);
        unsigned int len = 0;
        while(*s++ != '\0')
        {
                len++;
        }
        return len;
}
 
strstr()
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。
#include <assert.h>

const char* strstr(const char* src, const char* sub)
{
        //入口检查
        assert(src != NULL && sub != NULL);
        const char* bp;
        const char* sp;
        //
        while(*src)
        {
                bp = src;   //用于src遍历
                sp = sub;   //用于sub遍历
                //每一次src+1 ,然后与 sub 依次比较
                while(*bp++ == *sp++)
                {
                        if(!*sp)
                        {
                                //找到了
                                return src;
                        }
                }
                src++;
        }
        return NULL;
}

memset()

memset是计算机中C/C++语言函数。将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针

void* memset(void* str,int c, size_t n)
{
        assert(str != NULL);
        void* s = str;
        while(n--)
        {
                *(char*)s = (char)c;
                s = (char*)s+;
        }
        return str;
}

memcpy()

内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。

void* memcpy(void* dest, const void void* src, size_t n)
{
        assert(dest != NULL && src != NULL);
        
        char *temp = (char*)dest;
        char *s_src = (char*)src;
        while(n--)
        {
                *temp++ = *s_src++;
        }
        return dest;
}

memmove()

 memmove() 函数从src内存中拷贝n个字节到dest内存区域,但是源和目的的内存可以重叠。函数返回一个指向dest的指针。

memcpy与memmove唯一区别就是在对待重叠区域的时候,memmove可以正确的完成对应的拷贝,而memcpy不能。

内存覆盖的情形有以下两种,

void* memmove(void* dest, const void* src, size_t n)
{
        assert(dest != NULL && src != NULL);
        char* psrc = (char*)src;
        char* pdest = (char*)dest;
        //pdest在psrc后面,且两者距离小于n时,从尾部开始移动. 其他情况从头部开始移动 
        if(pdest > psrc && pdest-psrc <n)
        {
                pdest = pdest+n-1;  //以为第一个值为 p+0
                psrc = psrc+n-1;
                while(n--)
                {
                        *pdest-- = *psrc--;
                }
                else{
                        while(n--)
                        {
                                *pdest++ = *psrc++;
                        }
                }        
        }
        return dest;
        
}

 

posted @ 2017-04-13 17:25  ren_zhg1992  阅读(678)  评论(0编辑  收藏  举报