c语言str相关的函数

C语言str系列库函数在不同的库中有不同的实现方法,但原理都是一样的。因为库函数都是没有进行入口参数检查的,并且str系列库函数在面试中经常容易被面试官喊在纸上写某一个函数的实现,因此本文参考了OpenBSD和vc++ 8.0库中的代码,结合自己的编程习惯,部分整理如下:

1、strcpy

[cpp]  view plain  copy
  1. char * strcpy(char *dst, const char *src)  
  2. {  
  3.     char *d;  
  4.   
  5.     if (dst == NULL || src == NULL)  
  6.         return dst;  
  7.   
  8.     d = dst;  
  9.     while (*d++ = *src++)    // while ((*d++ = *src++) != '\0')  
  10.         ;  
  11.   
  12.     return dst;  
  13. }  

2、strncpy

[cpp]  view plain  copy
  1. //copy at most n characters of src to dst  
  2. //Pad with '\0' if src fewer than n characters  
  3. char *strncpy(char *dst, const char*src, size_t n)  
  4. {  
  5.     char *d;  
  6.   
  7.     if (dst == NULL || src == NULL)  
  8.         return dst;  
  9.   
  10.     d = dst;  
  11.     while (n != 0 && (*d++ = *src++))    /* copy string */  
  12.         n--;  
  13.     if (n != 0)  
  14.         while (--n != 0)  
  15.             *d++ == '\0';                /* pad out with zeroes */  
  16.   
  17.     return dst;  
  18. }  

注意 n是unsigned int,在进行n--操作时特别要小心。如果不小心写成下面这样就会出错:
[cpp]  view plain  copy
  1. while (n-- != 0 && (*d++ = *src++))  
  2.     ;         
  3. while (n-- != 0)   
  4.     *d++ = '\0';  
第一个while循环中,当n变为0时,仍然会执行n--一,此时n等于经由-1变成的大正数,导致后面对n的使用出错。

3、strcat

[cpp]  view plain  copy
  1. char *strcat(char *dst, const char *src)  
  2. {     
  3.     char *d;  
  4.     if (dst == NULL || src == NULL)  
  5.         return dst;  
  6.   
  7.    d = dst;  
  8.    while (*d)  
  9.        d++;  
  10.    //while (*d++ != 0);  
  11.    //d--;  
  12.      
  13.    while (*d++ = *src++)  
  14.        ;  
  15.   
  16.    return dst;  
  17. }  

4、strncat

写法1:
[cpp]  view plain  copy
  1. //concatenate at most n characters of src to the end of dst  
  2. //terminates dst with '\0'  
  3. char *strncat(char *dst, const char *src, size_t n)  
  4. {  
  5.     if (NULL == dst || NULL == src)  
  6.         return dst;  
  7.   
  8.     if (n != 0)  
  9.     {  
  10.         char *d = dst;  
  11.         do   
  12.         {  
  13.             if ((*d = *src++) == '\0' )  
  14.                 return dst;     //break  
  15.             d++;  
  16.         } while (--n != 0);    
  17.         *d = '\0';  
  18.     }  
  19.       
  20.     return dst;  
  21. }  
写法2:
[cpp]  view plain  copy
  1. char *strncat(char *dst, const char *src, size_t n)  
  2. {  
  3.    char *d;  
  4.   
  5.    if (dst == NULL || src == NULL)  
  6.        return dst;  
  7.      
  8.    d = dst;  
  9.    while (*d)  
  10.        d++;  
  11.    //(1)  
  12.    while (n != 0)  
  13.    {  
  14.        if ((*d++ = *src++) == '\0')  
  15.            return dst;  
  16.        n--;  
  17.    }  
  18.   
  19.    //(2)  
  20.    //while (n--)       //这种方式写最后n的值不为0,不过这个n后面不会再被使用  
  21.       // if ((*d++ == *src++) == '\0')  
  22.          //  return dst;  
  23.   
  24.    *d = '\0';  
  25.   
  26.    return dst;  
  27. }  

5、strcmp

[cpp]  view plain  copy
  1. int strcmp(const char *s1, const char *s2)  
  2. {   
  3.     if (s1 == NULL || s2 == NULL)  
  4.         return 0;  
  5.     //(1)  
  6.     //while (*s1 == *s2++)  
  7.     //  if (*s1++ == '\0')  
  8.     //      return 0;  
  9.   
  10.     //(2)  
  11.     for (; *s1 == *s2; s1++, s2++)  
  12.         if (*s1 == '\0')  
  13.             return 0;  
  14.     return *(unsigned char*)s1 - *(unsigned char*)s2;  
  15. }  

6、strncmp

[cpp]  view plain  copy
  1. int strncmp(const char *s1, const char *s2, size_t n)  
  2. {  
  3.     if (s1 == NULL || s2 == NULL)  
  4.         return 0;  
  5.   
  6.     if (n == 0)  
  7.         return 0;  
  8.     do  
  9.     {  
  10.         if (*s1 != *s2++)  
  11.             return *(unsigned char*)s1 - *(unsigned char*)--s2;  
  12.         if (*s1++ == '\0')  
  13.             break;  
  14.     } while (--n != 0);  
  15.   
  16.     //do   
  17.     //{  
  18.     //  if (*s1 != *s2)  
  19.     //      return *(unsigned char*)s1 - *(unsigned char*)s2;  
  20.     //  if (*s1 == '\0')  
  21.     //      break;  
  22.     //  s1++;  
  23.     //  s2++;  
  24.     //} while (--n != 0);  
  25.   
  26.     return 0;  
  27. }  

7、strstr

写法1:
[cpp]  view plain  copy
  1. //return pointer to first  occurrence of find in s  
  2. //or NULL if not present  
  3. char *strstr(const char *s, const char *find)  
  4. {  
  5.     char *cp = (char*)s;  
  6.     char *s1, *s2;  
  7.   
  8.     if (s == NULL || find == NULL)  
  9.         return NULL;  
  10.   
  11.     while (*cp != '\0')  
  12.     {  
  13.         s1 = cp;  
  14.         s2 = (char*)find;  
  15.   
  16.         while (*s1 && *s2 && *s1 == *s2)  
  17.             s1++, s2++;  
  18.   
  19.         if(*s2 == '\0')  
  20.             return cp;  
  21.   
  22.         cp++;  
  23.     }  
  24.    return NULL;  
  25. }  
写法2:参照简单模式匹配算法
[cpp]  view plain  copy
  1. char *strstr(const char *s, const char *find)  
  2. {  
  3.     int i = 0, j = 0;  
  4.     while (*(s + i) != '\0' && *(find + j) != '\0')  
  5.     {  
  6.         if (*(s + i + j) == *(find + j))  
  7.             j++;     //继续比较后一字符  
  8.         else  
  9.         {  
  10.             i++;     //开始新一轮比较  
  11.             j = 0;  
  12.         }  
  13.     }  
  14.   
  15.     return *(find + j) == '\0' ? (char*)(s + i) : NULL;  
  16. }  

8、strchr

[cpp]  view plain  copy
  1. //return pointer to first occurrence of ch in str  
  2. //NULL if not present  
  3. char *strchr(const char*str, int ch)  
  4. {  
  5.     while (*str != '\0' && *str != (char)ch)  
  6.         str++;  
  7.   
  8.     if(*str == (char)ch)  
  9.         return (char*)str;  
  10.     return NULL;  
  11. }  

9、strrchr

[cpp]  view plain  copy
  1. //return pointer to last occurrence of ch in str  
  2. //NULL if not present  
  3. char *strrchr(const char *str, int ch)  
  4. {  
  5.     if (str == NULL)  
  6.         return NULL;  
  7.   
  8.    char *s = (char*)str;  
  9.   
  10.    while (*s++)  
  11.        ;       /* find end of string */  
  12.   
  13.    while (--s != str && *s != (char)ch)  
  14.        ;       /* search towards front */  
  15.   
  16.    if(*s == (char)ch)  
  17.        return (char*)s;  
  18.    return NULL;  
  19. }  

10、strlen

[cpp]  view plain  copy
  1. size_t strlen(const char *str)  
  2. {  
  3.     if (str == NULL)  
  4.         return 0;  
  5.   
  6.     const char *eos = str;  
  7.     while (*eos++)  
  8.         ;  
  9.     return (eos - 1 - str);  
  10. }  

另外两篇str系列库函数:
C语言str系列库函数之strtok(): http://blog.csdn.net/u013071074/article/details/27716097
C语言str系列库函数之strspn()、strcspn()和strpbrk(): http://blog.csdn.net/u013071074/article/details/27808497

str系列库函数的使用实例: http://www.cplusplus.com/reference/cstring/
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值