• 字符串函数汇总


    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()函数用来做内存复制,可以拿他来复制任何数据类型的对象,可以指定复制的数据长度。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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的实现

    1
    2
    3
    4
    5
    6
    7
    8
    int strlen(const char *str)
    {
        int len=0;
        if(str==NULL)
            return len;
        while(*str++!='') len++;
        return len;
    }

    不使用变量,实现:

    1
    2
    3
    4
    5
    6
    7
    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;
    }
    复制代码

    现场编写类似strstr/strcpy/strpbrk的函数

    第一节、字符串查找
    1.1题目描述:
    给定一个字符串A,要求在A中查找一个子串B。
    如A="ABCDF",要你在A中查找子串B=“CD”。

    分析:比较简单,相当于实现strstr库函数,主体代码如下:

    1. //在字符串中查找指定字符串的第一次出现,不能找到则返回-1        
    2. int strstr(char *string, char *substring)        
    3. {       
    4.     if (string == NULL || substring == NULL)          
    5.         return -1;          
    6.   
    7.     int lenstr = strlen(string);       
    8.     int lensub = strlen(substring);       
    9.   
    10.     if (lenstr < lensub)          
    11.         return -1;           
    12.   
    13.     int len = lenstr - lensub;    
    14.     int i,j;  
    15.     for (i = 0; i <= len; i++)   //复杂度为O(m*n)       
    16.     {       
    17.         for (j = 0; j < lensub; j++)       
    18.         {       
    19.             if (string[i+j] != substring[j])       
    20.                 break;       
    21.         }       
    22.         if (j == lensub)       
    23.             return i + 1;       
    24.     }       
    25.     return -1;       
    26. }      

        读者反馈@xiaohui5319:楼主啊,对于你那个strstr的函数,我觉得有点小问题。我查了一下C标准库的源码,它给的声明是这样的,两个参数都有const。

    char *

    STRSTR (const char *haystack_start, const char *needle_start)

        而且标准库中没有调用strlen函数,因为假如你是标准库的设计者,strlen()函数还没设计出来,你怎么去计算两个字符串的长度?是不是只能通过指针移动来实现,我觉得这些都是微软要考察的地方。

        此外:还有int lenstr=strlen(string);这是不安全的?
        strlen函数的返回类型是size_t型,也就是无符号整型,假如我的数组长度很长(假如是用堆分配的,可以很大很大),长过2的31次方减1的话,会发生一处,你这lenstr就会变成负值了
        用size_t类型最保险。

        以后,本编程艺术系列中有任何问题,暂未来得及及时修正,请读者多加思考,多加辨明。

        上述程序已经实现了在字符串中查找第一个子串的功能,时间复杂度为O(n*m),也可以用KMP算法,复杂度为O(m+n)。为人打通思路,提高他人创造力,我想,这是狂想曲与其它的面试解答所不同的地方,也是我们写狂想曲系列文章的意义与价值之所在。

    1.2、题目描述

    在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。 

    代码则可以如下编写:

    1. //查找第一个只出现一次的字符,       
    2. //copyright@ yansha       
    3. //July、updated,2011.04.24.       
    4. char FirstNotRepeatChar(char* pString)       
    5. {       
    6.     if(!pString)       
    7.         return '';       
    8.   
    9.     const int tableSize = 256;      
    10.     //有点要提醒各位注意,一般常数的空间消耗,如这里的256,我们也认为此空间复杂度为O(1)。    
    11.     int hashTable[tableSize] = {0}; //存入数组,并初始化为0       
    12.   
    13.     char* pHashKey = pString;       
    14.     while(*(pHashKey) != '')       
    15.         hashTable[*(pHashKey++)]++;       
    16.   
    17.     while(*pString != '')       
    18.     {       
    19.         if(hashTable[*pString] == 1)       
    20.             return *pString;       
    21.   
    22.         pString++;       
    23.     }       
    24.     return '';  //没有找到满足条件的字符,退出       
    25. }    

    代码二,bitmap:

    1. # include<stdio.h>    
    2. # include<string.h>    
    3.   
    4. const int N = 26;    
    5. int bit_map[N];    
    6.   
    7. void findNoRepeat(char *src)    
    8. {    
    9.     int pos;    
    10.     char *str = src;    
    11.     int i ,len = strlen(src);    
    12.   
    13.     //统计    
    14.     for(i = 0 ; i < len ;i ++)    
    15.         bit_map[str[i]-'a'] ++;    
    16.   
    17.     //从字符串开始遍历 其bit_map==1 那么就是结果    
    18.     for(i = 0 ; i < len ; i ++)    
    19.     {    
    20.         if(bit_map[str[i]-'a'] == 1)    
    21.         {    
    22.             printf("%c",str[i]);    
    23.             return ;    
    24.         }    
    25.     }    
    26. }    
    27.   
    28. int main()    
    29. {       
    30.     char *src = "abaccdeff";    
    31.     findNoRepeat(src);    
    32.     printf(" ");    
    33.     return 0;    
    34. }    


    第二节、字符串拷贝
    题目描述:
    要求实现库函数strcpy,
    原型声明:extern char *strcpy(char *dest,char *src);
    功能:把src所指由NULL结束的字符串复制到dest所指的数组中。  
    说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。  
    返回指向dest的指针。

        分析:如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:

    1. //得2分       
    2. void strcpy( char *strDest, char *strSrc )       
    3. {       
    4.     while( (*strDest++ = * strSrc++) != '' );       
    5. }        
    6.   
    7. //得4分       
    8. void strcpy( char *strDest, const char *strSrc )        
    9. {       
    10.     //将源字符串加const,表明其为输入参数,加2分       
    11.     while( (*strDest++ = * strSrc++) != '' );       
    12. }        
    13.   
    14. //得7分       
    15. void strcpy(char *strDest, const char *strSrc)        
    16. {       
    17.     //对源地址和目的地址加非0断言,加3分       
    18.     assert( (strDest != NULL) && (strSrc != NULL) );       
    19.     while( (*strDest++ = * strSrc++) != '' );       
    20. }        
    21.   
    22. //得9分       
    23. //为了实现链式操作,将目的地址返回,加2分!       
    24. char * strcpy( char *strDest, const char *strSrc )        
    25. {       
    26.     assert( (strDest != NULL) && (strSrc != NULL) );       
    27.     char *address = strDest;        
    28.     while( (*strDest++ = * strSrc++) != '' );        
    29.     return address;       
    30. }      
    31.   
    32. //得10分,基本上所有的情况,都考虑到了    
    33. //如果有考虑到源目所指区域有重叠的情况,加1分!       
    34. char * strcpy( char *strDest, const char *strSrc )        
    35. {       
    36.     if(strDest == strSrc) { return strDest; }    
    37.     assert( (strDest != NULL) && (strSrc != NULL) );       
    38.     char *address = strDest;        
    39.     while( (*strDest++ = * strSrc++) != '' );        
    40.     return address;       
    41. }  


    第三节、小部分库函数的实现
        考察此类编写同库函数一样功能的函数经常见于大大小小的IT公司的面试题目中,以下是常见的字符串库函数的实现,希望,对你有所帮助,有任何问题,欢迎不吝指正:

    1. //@yansha:字串末尾要加结束符'',不然输出错位结果    
    2. char *strncpy(char *strDes, const char *strSrc, unsigned int count)        
    3. {        
    4.     assert(strDes != NULL && strSrc != NULL);        
    5.     char *address = strDes;        
    6.     while (count-- && *strSrc != '')        
    7.         *strDes++ = *strSrc++;     
    8.     *strDes = '';    
    9.     return address;        
    10. }     
    11.   
    12. //查找字符串s中首次出现字符c的位置     
    13. char *strchr(const char *str, int c)     
    14. {     
    15.     assert(str != NULL);     
    16.     for (; *str != (char)c; ++ str)     
    17.         if (*str == '')     
    18.             return NULL;     
    19.         return str;     
    20. }     
    21.   
    22. int strcmp(const char *s, const char *t)     
    23. {     
    24.     assert(s != NULL && t != NULL);     
    25.     while (*s && *t && *s == *t)     
    26.     {     
    27.         ++ s;     
    28.         ++ t;     
    29.     }     
    30.     return (*s - *t);     
    31. }     
    32.   
    33. char *strcat(char *strDes, const char *strSrc)     
    34. {     
    35.     assert((strDes != NULL) && (strSrc != NULL));     
    36.     char *address = strDes;     
    37.     while (*strDes != '')     
    38.         ++ strDes;     
    39.     while ((*strDes ++ = *strSrc ++) != '')     
    40.         NULL;     
    41.     return address;     
    42. }     
    43.   
    44. int strlen(const char *str)     
    45. {     
    46.     assert(str != NULL);     
    47.     int len = 0;     
    48.     while (*str ++ != '')     
    49.         ++ len;     
    50.     return len;     
    51. }     
    52.   
    53. //此函数,梦修改如下       
    54. char *strdup_(char *strSrc)       
    55. //将字符串拷贝到新的位置       
    56. {       
    57.     if(strSrc!=NULL)       
    58.     {       
    59.         char *start=strSrc;       
    60.         int len=0;       
    61.         while(*strSrc++!='')       
    62.             len++;       
    63.   
    64.         char *address=(char *)malloc(len+1);       
    65.         assert(address != NULL);    
    66.   
    67.         while((*address++=*start++)!='');        
    68.         return address-(len+1);        
    69.     }       
    70.     return NULL;       
    71. }       
    72.   
    73. //多谢laoyi19861011指正    
    74. char *strstr(const char *strSrc, const char *str)     
    75. {     
    76.     assert(strSrc != NULL && str != NULL);     
    77.     const char *s = strSrc;     
    78.     const char *t = str;     
    79.     for (; *strSrc != ''; ++ strSrc)     
    80.     {     
    81.         for (s = strSrc, t = str; *t != '' && *s == *t; ++s, ++t)     
    82.             NULL;     
    83.         if (*t == '')     
    84.             return (char *) strSrc;     
    85.     }     
    86.     return NULL;     
    87. }     
    88.   
    89. char *strncat(char *strDes, const char *strSrc, unsigned int count)     
    90. {     
    91.     assert((strDes != NULL) && (strSrc != NULL));     
    92.     char *address = strDes;     
    93.     while (*strDes != '')     
    94.         ++ strDes;     
    95.     while (count -- && *strSrc != '' )     
    96.         *strDes ++ = *strSrc ++;     
    97.     *strDes = '';     
    98.     return address;     
    99. }     
    100.   
    101. int strncmp(const char *s, const char *t, unsigned int count)     
    102. {     
    103.     assert((s != NULL) && (t != NULL));     
    104.     while (*s && *t && *s == *t && count --)     
    105.     {     
    106.         ++ s;     
    107.         ++ t;     
    108.     }     
    109.     return (*s - *t);     
    110. }     
    111.   
    112. char *strpbrk(const char *strSrc, const char *str)     
    113. {     
    114.     assert((strSrc != NULL) && (str != NULL));     
    115.     const char *s;     
    116.     while (*strSrc != '')     
    117.     {     
    118.         s = str;     
    119.         while (*s != '')     
    120.         {     
    121.             if (*strSrc == *s)     
    122.                 return (char *) strSrc;     
    123.             ++ s;     
    124.         }     
    125.         ++ strSrc;     
    126.     }     
    127.     return NULL;     
    128. }     
    129.   
    130. int strcspn(const char *strSrc, const char *str)     
    131. {     
    132.     assert((strSrc != NULL) && (str != NULL));     
    133.     const char *s;     
    134.     const char *t = strSrc;     
    135.     while (*t != '')     
    136.     {     
    137.         s = str;     
    138.         while (*s != '')     
    139.         {     
    140.             if (*t == *s)     
    141.                 return t - strSrc;     
    142.             ++ s;     
    143.         }     
    144.         ++ t;     
    145.     }     
    146.     return 0;     
    147. }     
    148.   
    149. int strspn(const char *strSrc, const char *str)     
    150. {     
    151.     assert((strSrc != NULL) && (str != NULL));     
    152.     const char *s;     
    153.     const char *t = strSrc;     
    154.     while (*t != '')     
    155.     {     
    156.         s = str;     
    157.         while (*s != '')     
    158.         {     
    159.             if (*t == *s)     
    160.                 break;     
    161.             ++ s;     
    162.         }     
    163.         if (*s == '')     
    164.             return t - strSrc;     
    165.         ++ t;     
    166.     }     
    167.     return 0;     
    168. }     
    169.   
    170. char *strrchr(const char *str, int c)     
    171. {     
    172.     assert(str != NULL);     
    173.     const char *s = str;     
    174.     while (*s != '')     
    175.         ++ s;     
    176.     for (-- s; *s != (char) c; -- s)     
    177.         if (s == str)     
    178.             return NULL;     
    179.         return (char *) s;     
    180. }     
    181.   
    182. char* strrev(char *str)     
    183. {     
    184.     assert(str != NULL);     
    185.     char *s = str, *t = str, c;     
    186.     while (*t != '')     
    187.         ++ t;     
    188.     for (-- t; s < t; ++ s, -- t)     
    189.     {     
    190.         c = *s;     
    191.         *s = *t;     
    192.         *t = c;     
    193.     }     
    194.     return str;     
    195. }     
    196.   
    197. char *strnset(char *str, int c, unsigned int count)     
    198. {     
    199.     assert(str != NULL);     
    200.     char *s = str;     
    201.     for (; *s != '' && s - str < count; ++ s)     
    202.         *s = (char) c;     
    203.     return str;     
    204. }     
    205.   
    206. char *strset(char *str, int c)     
    207. {     
    208.     assert(str != NULL);     
    209.     char *s = str;     
    210.     for (; *s != ''; ++ s)     
    211.         *s = (char) c;     
    212.     return str;     
    213. }     
    214.   
    215. //@heyaming    
    216. //对原 strtok 的修改,根据MSDN,strToken可以为NULL.实际上第一次call strtok给定一字串,    
    217. //再call strtok时可以输入NULL代表要接着处理给定字串。    
    218. //所以需要用一 static 保存没有处理完的字串。同时也需要处理多个分隔符在一起的情况。    
    219. char *strtok(char *strToken, const char *str)    
    220. {    
    221.     assert(str != NULL);    
    222.     static char *last;    
    223.   
    224.     if (strToken == NULL && (strToken = last) == NULL)    
    225.         return (NULL);    
    226.   
    227.     char *s = strToken;    
    228.     const char *t = str;    
    229.     while (*s != '')    
    230.     {    
    231.         t = str;    
    232.         while (*t != '')    
    233.         {    
    234.             if (*s == *t)    
    235.             {    
    236.                 last = s + 1;    
    237.                 if (s - strToken == 0) {    
    238.                     strToken = last;    
    239.                     break;    
    240.                 }    
    241.                 *(strToken + (s - strToken)) = '';    
    242.                 return strToken;    
    243.             }    
    244.             ++ t;    
    245.         }    
    246.         ++ s;    
    247.     }    
    248.     return NULL;    
    249. }    
    250.   
    251. char *strupr(char *str)     
    252. {     
    253.     assert(str != NULL);     
    254.     char *s = str;     
    255.     while (*s != '')     
    256.     {     
    257.         if (*s >= 'a' && *s <= 'z')     
    258.             *s -= 0x20;     
    259.         s ++;     
    260.     }     
    261.     return str;     
    262. }     
    263.   
    264. char *strlwr(char *str)     
    265. {     
    266.     assert(str != NULL);     
    267.     char *s = str;     
    268.     while (*s != '')     
    269.     {     
    270.         if (*s >= 'A' && *s <= 'Z')     
    271.             *s += 0x20;     
    272.         s ++;     
    273.     }     
    274.     return str;     
    275. }     
    276.   
    277. void *memcpy(void *dest, const void *src, unsigned int count)     
    278. {     
    279.     assert((dest != NULL) && (src != NULL));     
    280.     void *address = dest;     
    281.     while (count --)     
    282.     {     
    283.         *(char *) dest = *(char *) src;     
    284.         dest = (char *) dest + 1;     
    285.         src = (char *) src + 1;     
    286.     }     
    287.     return address;     
    288. }     
    289.   
    290. void *memccpy(void *dest, const void *src, int c, unsigned int count)     
    291. {     
    292.     assert((dest != NULL) && (src != NULL));     
    293.     while (count --)     
    294.     {     
    295.         *(char *) dest = *(char *) src;     
    296.         if (* (char *) src == (char) c)     
    297.             return ((char *)dest + 1);     
    298.         dest = (char *) dest + 1;     
    299.         src = (char *) src + 1;     
    300.     }     
    301.     return NULL;     
    302. }     
    303.   
    304. void *memchr(const void *buf, int c, unsigned int count)     
    305. {     
    306.     assert(buf != NULL);     
    307.     while (count --)     
    308.     {     
    309.         if (*(char *) buf == c)     
    310.             return (void *) buf;     
    311.         buf = (char *) buf + 1;     
    312.     }     
    313.     return NULL;     
    314. }     
    315.   
    316. int memcmp(const void *s, const void *t, unsigned int count)     
    317. {     
    318.     assert((s != NULL) && (t != NULL));     
    319.     while (*(char *) s && *(char *) t && *(char *) s == *(char *) t && count --)     
    320.     {     
    321.         s = (char *) s + 1;     
    322.         t = (char *) t + 1;     
    323.     }     
    324.     return (*(char *) s - *(char *) t);     
    325. }     
    326.   
    327. //@big:    
    328. //要处理src和dest有重叠的情况,不是从尾巴开始移动就没问题了。    
    329. //一种情况是dest小于src有重叠,这个时候要从头开始移动,    
    330. //另一种是dest大于src有重叠,这个时候要从尾开始移动。    
    331. void *memmove(void *dest, const void *src, unsigned int count)     
    332. {    
    333.     assert(dest != NULL && src != NULL);    
    334.     char* pdest = (char*) dest;    
    335.     char* psrc = (char*) src;    
    336.   
    337.     //pdest在psrc后面,且两者距离小于count时,从尾部开始移动. 其他情况从头部开始移动    
    338.     if (pdest > psrc && pdest - psrc < count)     
    339.     {    
    340.         while (count--)     
    341.         {    
    342.             *(pdest + count) = *(psrc + count);    
    343.         }    
    344.     } else     
    345.     {    
    346.         while (count--)     
    347.         {    
    348.             *pdest++ = *psrc++;    
    349.         }    
    350.     }    
    351.     return dest;    
    352. }    
    353.   
    354. void *memset(void *str, int c, unsigned int count)     
    355. {     
    356.     assert(str != NULL);     
    357.     void *s = str;     
    358.     while (count --)     
    359.     {     
    360.         *(char *) s = (char) c;     
    361.         s = (char *) s + 1;     
    362.     }     
    363.     return str;     
    364. }    

     
      测试:以上所有的函数,都待进一步测试,有任何问题,欢迎任何人随时不吝指出。

    第四节、c标准库部分源代码

        为了给各位一个可靠的参考,以下,我摘取一些c标准框里的源代码,以飨各位:

    1. char * __cdecl strcat (char * dst,const char * src)    
    2. {    
    3.     char * cp = dst;    
    4.   
    5.     while( *cp )    
    6.         cp++;                   /* find end of dst */    
    7.   
    8.     while( *cp++ = *src++ ) ;       /* Copy src to end of dst */    
    9.   
    10.     return( dst );                  /* return dst */    
    11.   
    12. }    
    13.   
    14. int __cdecl strcmp (const char * src,const char * dst)    
    15. {    
    16.     int ret = 0 ;    
    17.   
    18.     while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)    
    19.         ++src, ++dst;    
    20.   
    21.     if ( ret < 0 )    
    22.         ret = -1 ;    
    23.     else if ( ret > 0 )    
    24.         ret = 1 ;    
    25.   
    26.     return( ret );    
    27. }    
    28.   
    29. size_t __cdecl strlen (const char * str)    
    30. {    
    31.     const char *eos = str;    
    32.   
    33.     while( *eos++ ) ;    
    34.   
    35.     return( (int)(eos - str - 1) );    
    36. }    
    37.   
    38. char * __cdecl strncat (char * front,const char * back,size_t count)    
    39. {    
    40.     char *start = front;    
    41.   
    42.     while (*front++)    
    43.         ;    
    44.     front--;    
    45.   
    46.     while (count--)    
    47.         if (!(*front++ = *back++))    
    48.             return(start);    
    49.   
    50.         *front = '';    
    51.         return(start);    
    52. }    
    53.   
    54. int __cdecl strncmp (const char * first,const char * last,size_t count)    
    55. {    
    56.     if (!count)    
    57.         return(0);    
    58.   
    59.     while (--count && *first && *first == *last)    
    60.     {    
    61.         first++;    
    62.         last++;    
    63.     }    
    64.   
    65.     return( *(unsigned char *)first - *(unsigned char *)last );    
    66. }    
    67.   
    68. /* Copy SRC to DEST.  */    
    69. char *    
    70. strcpy (dest, src)    
    71. char *dest;    
    72. const char *src;    
    73. {    
    74.     reg_char c;    
    75.     char *__unbounded s = (char *__unbounded) CHECK_BOUNDS_LOW (src);    
    76.     const ptrdiff_t off = CHECK_BOUNDS_LOW (dest) - s - 1;    
    77.     size_t n;    
    78.   
    79.     do    
    80.     {    
    81.         c = *s++;    
    82.         s[off] = c;    
    83.     }    
    84.     while (c != '');    
    85.   
    86.     n = s - src;    
    87.     (void) CHECK_BOUNDS_HIGH (src + n);    
    88.     (void) CHECK_BOUNDS_HIGH (dest + n);    
    89.   
    90.     return dest;    
    91. }    
    92.   
    93. char * __cdecl strncpy (char * dest,const char * source,size_t count)    
    94. {    
    95.     char *start = dest;    
    96.   
    97.     while (count && (*dest++ = *source++))    /* copy string */    
    98.         count--;    
    99.   
    100.     if (count)                              /* pad out with zeroes */    
    101.         while (--count)    
    102.             *dest++ = '';    
    103.   
    104.         return(start);    
    105. }  
  • 相关阅读:
    学习笔记: yield迭代器
    学习笔记: 委托解析和封装,事件及应用
    学习笔记: MD5/DES/RSA三类加密,SSL协议解析
    学习笔记: Expression表达式目录树详解和扩展封装
    学习笔记: Expression表达式目录树详解和扩展封装
    学习笔记: IO操作及序列化
    数据类型转换
    短路运算(逻辑运算是短路运算中最常见的一种)
    清除浮动
    css初始化
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8460932.html
Copyright © 2020-2023  润新知