zoukankan      html  css  js  c++  java
  • 常用字符串函数编写

    已有代码在linux-gcc中编译通过

      1 #include <stdio.h>
      2 #include <assert.h>
      3 #include <string.h>
      4 #include <stdlib.h>
      5 
      6 // 内存copy函数
      7 void *my_memcpy(void *dest, const void *src, int n)
      8 {
      9     assert((NULL != dest) && (NULL != src));    //判断指针的有效性
     10     char *pdest = (char *)dest;              
     11     char *psrc = (char *)src;       //转换成char类型,一个字节一个字节的传输
     12     while(n--)
     13         *pdest++ = *psrc++;     //每次传输一字节
     14     return pdest;
     15 }
     16 
     17 /**
     18  * memcpy在内存没有重复的情况下能够正确复制,若有重叠情况则复制结果错误,但是它的效率比memmove高。
     19  * 所以,在确定没有重复的情况下用memcpy,在不确定是否有内存重复的情况用memmove。
     20  */
     21 void *my_memmove(void *dest, const void *src, int n)
     22 {
     23     assert((NULL != dest) && (NULL != src));
     24     char *pdest = (char *)dest;                 //转换成char类型,一个字节一个字节的传输
     25     char *psrc = (char *)src;   
     26     if((pdest <= psrc) || (pdest >= psrc + n))  //从前往后复制,则不会出现覆盖src中没有复制的内容
     27     {
     28         while(n--)
     29             *pdest++ = *psrc++;
     30     }
     31     else
     32     {
     33         pdest = pdest + n -1;   //有内存重叠时,从高字节开始传输
     34         psrc = psrc + n -1;     //移动到末尾
     35         while(n--)
     36         *pdest-- = *psrc--; //每次移动一个字节
     37     }
     38     return pdest;
     39 }
     40 
     41 // 作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c。
     42 void *my_memset(void *s, int c, int n)
     43 {
     44     assert(NULL != s);
     45     unsigned char *buff = (char *)s;
     46     while(n--)
     47     {
     48         *(buff++) = (char)c;
     49     }
     50     return buff;
     51 }
     52 
     53 /** memcmp函数会逐字节比较s1和s2所指内存区,
     54  * s1 > s2 —-> 返回 >0 的值 
     55  * s1 = s2 —-> 返回 =0 的值 
     56  * s1 < s2 —-> 返回 <0 的值
     57  */
     58 int my_memcmp(const void *s1, const void *s2, int n)
     59 {
     60     assert((NULL != s1) && (NULL != s2));
     61 
     62     int result;
     63     while(!(result = *(unsigned char *)s1 - *(unsigned char *)s2) && (n--))
     64     {
     65         s1++; s2++;
     66     }
     67     return result;
     68     
     69 }
     70 
     71 // 当第一次遇到字符c时停止查找。如果成功,返回指向字符c的指针;否则返回NULL。
     72 void *my_memchr(const void *s, int c, int n)
     73 {
     74     assert(NULL != s);
     75     int result;
     76     while((*(unsigned char *)(s) != (unsigned char)c) && (n--))
     77     {
     78         s++;
     79     }
     80         return (n ? (void *)s : NULL);
     81 }
     82 
     83 char *my_strcpy(char *dest, const char *src)
     84 {
     85     assert((NULL != dest) && (NULL != src));//判断指针的有效性
     86     char *addr = dest;
     87     while((*dest++ = *src++) != '');
     88     return addr;            //返回 char *,使函数支持链式表达式
     89 }
     90 
     91 char *my_strncpy(char *dest, const char *src, int n)
     92 {
     93     assert((NULL != dest) && (NULL != src));
     94     char *addr = dest;
     95     while((n--) && (*dest++ = *src++) != '');
     96     return addr;            //返回 char *,使函数支持链式表达式
     97 }
     98 
     99 char *my_strcat(char *dest, const char *src)
    100 {
    101     assert((NULL != dest) && (NULL != src));
    102     char *addr = dest;
    103     while(*dest!= '') //若使用while(*strDest++),则会出错,因为++是不受循环约束的
    104     {
    105         *dest++;    //要使dest最后指向该字符的结束标志,就必须在内部循环
    106     }
    107     while((*dest++ = *src++) != '');
    108     return addr;    //为了实现链式操作,将目的地址返回
    109 }
    110 
    111 /**
    112  * my_strncat其原理与my_strcat相同,只是在判断条件中加入边界条件;
    113  * while(((i++ < n) && (*dest++ = *src++)) != '')中,i++<n 为边界,当i = n-1时,退出循环
    114  */
    115 char *my_strncat(char *dest, const char *src, int n)
    116 {
    117     assert((NULL != dest) && (NULL != src));
    118     char *addr = dest;
    119     while(*dest != '')
    120     {
    121         *dest++;
    122     }
    123     while((n--) && (*dest++ = *src++) != '');
    124     return addr;
    125 }
    126 
    127 /**
    128  * 使用*(unsignedchar*)str1而不是用*str1。这是因为传入的参数为有符号数,有符号字符值的范围
    129  * 是-128~127,无符号字符值的范围是0~255,而字符串的ASCII没有负值,若不转化为无符号数这会在
    130  * 减法实现时出现错误。例如str1的值为1,str2的值为255。
    131  *
    132  * While循环中(!(result = *(unsigned char *)s1 - *(unsigned char *)s2) && *s1),最后与上str1
    133  * 也可以换成str2,因为前面已经做了相减,无论哪个先为‘’都会退出。因为最后与上str1是为了判
    134  * 断str1是否结束,即是否为‘’。
    135  */
    136 int my_strcmp(const char *s1, const char *s2)
    137 {
    138     assert((NULL != s1) && (NULL != s2));
    139     int result;
    140     while(!(result = *(unsigned char *)s1 - *(unsigned char *)s2) && *s1)
    141     {
    142         s1++; s2++; //字符串比较是一位一位的比较,s1++,s2++的作用是循环比较下一位
    143     }
    144     if(result > 0) {return 1;}
    145     else if(result < 0) {return -1;}
    146     else {return 0;}
    147 }
    148 
    149 /**
    150  * my_strncmp的实现原理与my_strcmp相同,但是相对于my_strcmp多了边界条件n;
    151  */
    152 int my_strncmp(const char *s1, const char *s2, int n)
    153 {
    154     
    155     assert((NULL != s1) && (NULL != s2));
    156     int result;
    157     while(!(result = *(unsigned char *)s1 - *(unsigned char *)s2) && *s1 && (n--))
    158     {
    159         s1++; s2++;
    160     }
    161     if(result > 0) {return 1;}
    162     else if(result < 0) {return -1;}
    163     else {return 0;}
    164 
    165 }
    166 
    167 // 查找字符串s中首次出现字符c的位置
    168 char *my_strchr(const char *s, int c)
    169 {
    170     assert(NULL != s);
    171     while(*s != (char)c)
    172     {   
    173         if ( *s == '' )
    174             return NULL;
    175         s++;
    176     }
    177     return (char *)s;
    178 
    179 }
    180 
    181 int my_strlen(const char *str)
    182 {
    183     assert(NULL != str);
    184     int len = 0;
    185     while(*str++ != '')   //strlen计算字符长度是不计算''的,这是函数原型决定的
    186     {
    187         len++;
    188     }
    189     return len;
    190 }
    191 
    192 char *my_strdup(const char *src)
    193 {
    194     assert(NULL !=src);
    195     char *psrc = (char *)src;
    196     char *p_src = NULL;
    197     p_src = psrc ;
    198     int len = 0 + 1;
    199     while(*p_src++ != '')
    200          len++;
    201     p_src = psrc;
    202     char *new_addr  = (char *)malloc(sizeof(char)*(len));
    203     while((*new_addr++ = *p_src++)  != '');
    204     return (new_addr - len);
    205 }
    206 
    207 char *my_strndup(const char *s, int n)
    208 {
    209     assert(NULL != s);
    210     
    211 }
    212 
    213 //搜索一个字符串 *needle 在 *haystack 字符串中的第一次出现。
    214 char *my_strstr(const char *haystack, const char *needle)
    215 {
    216     assert((NULL != haystack) && (NULL != needle));
    217     while(*haystack++ !='')
    218     {
    219         if((*haystack - *needle) == 0)
    220             return (char *)haystack;
    221         haystack++;
    222     }
    223     return NULL;
    224 }
    225 
    226 char *my_strtok(char *str, const char *delim)
    227 {
    228     
    229 }
    230 int my_strcoll(const char *s1, const char *s2)
    231 {
    232     
    233 }
    234 
    235 int main(void)
    236 {
    237     char dest[20] = {}, src[] = "abcde";
    238     char dest1[20] = {}, src1[] = "linux";
    239 
    240 /*    //my_memcpy功能验证
    241     printf("my_strcpy= %s
    ", my_strcpy(dest1, src1));
    242     printf("strcpy   = %s
    ", strcpy(dest, src));
    243 
    244     // memcpy(dest+2, dest, 5); 
    245     // printf("memcpy   = %s
    ", dest);//输出:my_memcpy  = abababa
    246     // memcpy(dest, dest1, strlen(dest1)); 
    247     // printf("memcpy   = %s
    ", dest);//输出:my_memcpy  = linuxba  
    248 
    249     my_memcpy(dest+2, dest, 5); 
    250     printf("my_memcpy= %s
    ", dest);//输出:my_memcpy  = abababa
    251     my_memcpy(dest, dest1, strlen(dest1)); 
    252     printf("my_memcpy= %s
    ", dest);//输出:my_memcpy  = linuxba      
    253 */ 
    254 
    255 /*    //my_memmove功能验证
    256     printf("my_strcpy= %s
    ", my_strcpy(dest1, src1));
    257     printf("strcpy   = %s
    ", strcpy(dest, src));
    258 
    259     // memmove(dest+2, dest, 5); 
    260     // printf("memmove  = %s
    ", dest);    //输出:memmove  = ababcde
    261     // memmove(dest, dest1, strlen(dest1)); 
    262     // printf("memmove  = %s
    ", dest);    //输出:memmove  = linuxde
    263      
    264     my_memmove(dest+2, dest, 5);
    265     printf("my_memmove  = %s
    ", dest);//输出:my_memmove  = ababcde
    266     my_memmove(dest, dest1, strlen(dest1)); 
    267     printf("my_memmove  = %s
    ", dest);//输出:my_memmove  = linuxde            
    268 */   
    269 
    270 /*    //my_memset功能验证
    271     my_memset(dest, '2', 20);
    272     printf("my_memset  = %s
    ", dest);  //输出:22222222222222222222
    273     memset(dest, 'A', 5);
    274     printf("memset     = %s
    ", dest);  //输出:AAAAA222222222222222
    275 */
    276 
    277 /*    //my_memcmp功能验证
    278     printf("dest1     = %s
    ", my_strncpy(dest1, src1,5));  //dest1 = linux
    279     printf("dest      = %s
    ", my_strncpy(dest, src, 5));   //dest  = liabc
    280     
    281     printf("my_memcmp = %d
    ", my_memcmp(dest1, dest, 2));
    282     printf("memcmp    = %d
    ", memcmp(dest1, dest, 3));
    283 
    284 */
    285 
    286 /*    //my_memchr功能验证
    287 
    288     printf("dest  = %s
    ", my_strcpy(dest, "arm - linux - gcc"));
    289     printf("dest1 = %s
    ", my_strcpy(dest1, "gcc"));
    290  
    291     printf("dest1:%s =%s
    ",dest1,(char *)memchr(dest,'-',my_strlen(dest)));
    292     printf("dest1:%s =%s
    ",dest1,(char *)my_memchr(dest,'-',my_strlen(dest)));
    293 */
    294 
    295 /*    //my_strcpy功能验证
    296     printf("my_strcpy  = %s
    ", my_strcpy(dest1, src1));
    297     printf("strcpy     = %s
    ", strcpy(dest, src));
    298 */
    299 
    300 /*    //my_strncpy功能验证
    301     printf("my_strncpy = %s
    ", my_strncpy(dest1, src1, 5));
    302     printf("strncpy    = %s
    ", strncpy(dest, src, 5));
    303 */
    304 
    305 
    306 /*    //my_strcat功能验证
    307     printf("my_strncpy = %s
    ", my_strncpy(dest1, src1, 2));
    308     printf("my_strcat  = %s
    ", my_strcat(dest1, src1));
    309     printf("strcat     = %s
    ", strcat(dest1, src));
    310 */
    311 
    312 /*    //my_strncat功能验证
    313     printf("my_strncpy = %s
    ", my_strncpy(dest1, src1, 2));
    314     printf("my_strncat = %s
    ", my_strncat(dest1, src1, 2));
    315     printf("strncat    = %s
    ", strncat(dest1, src, 2));
    316 */
    317 
    318 /*    //my_strcmp功能验证
    319     printf("my_strncat = %s
    ", my_strncat(dest1, src1, 3));
    320     printf("my_strncat = %s
    ", my_strncat(dest, src1, 2));
    321     printf("my_strcmp  = %d
    ", my_strcmp(dest1, dest));
    322     printf("   strcmp  = %d
    ", strcmp(dest1, dest));
    323     printf("my_strcmp  = %d
    ", my_strcmp(src, src1));
    324     printf("   strcmp  = %d
    ", strcmp(src, src1));
    325 */
    326 
    327 /*    //my_strncmp功能验证
    328     printf("my_strncpy  = %s
    ", my_strncpy(dest1, src1,5));
    329     printf("my_strncpy  = %s
    ", my_strncpy(dest, src, 5));
    330     printf("my_strncmp  = %d
    ", my_strncmp(dest1, dest, 1));
    331     printf("   strncmp  = %d
    ", strncmp(dest1, dest, 1));
    332     printf("my_strncmp  = %d
    ", my_strncmp(src, src1, 1));
    333     printf("   strncmp  = %d
    ", strncmp(src, src1, 1));
    334 */
    335 
    336 /*    //my_strchr功能验证
    337     char *dest2 = "arm-linux-gcc";
    338     
    339     printf("strchr    = %s
    ", strchr(dest2, 'r'));
    340     printf("my_strchr = %s
    ", my_strchr(dest2, 'r'));
    341 */
    342 
    343     
    344 /*    //my_strlen功能验证
    345     printf("my_strncpy = %s
    ", my_strncpy(dest1, src1, 5));
    346     printf("my_strlen  = %d
    ", my_strlen(dest1));
    347     printf("strlen     = %d
    ", strlen(dest1));  
    348 */
    349 
    350 /*    //my_strdup功能验证
    351     char *src2 = "arm-linux-gcc";
    352     char *dest2 , *dest3;
    353     dest2 = strdup(src2);
    354     dest3 = my_strdup(src2);
    355     printf("strdup string is: %s
    ", dest2);
    356     printf("strdup string is: %p
    ", dest2);
    357     printf("my_strdup string is: %s
    ", dest3);
    358     printf("my_strdup string is: %p
    ", dest3);
    359     free(dest2);
    360     free(dest3);
    361 */
    362 
    363 /*    //my_strndup功能验证
    364     char *src2 = "arm-linux-gcc";
    365     char *dest2 , *dest3;
    366     dest2 = strndup(src2, 2);
    367     dest3 = my_strndup(src2, 2);
    368     printf("strndup string is: %s
    ", dest2);
    369     printf("strndup string is: %p
    ", dest2);
    370     printf("my_strndup string is: %s
    ", dest3);
    371     printf("my_strndup string is: %p
    ", dest3);
    372    // free(dest2);
    373    // free(dest3);
    374 */
    375 
    376 ///*    //my_strstr功能验证
    377     char *src2 = "arm-linux-gcc";
    378     char *dest2= "ux";
    379     char *dest3, *dest4;
    380 
    381     dest3 = my_strstr(src2, dest2);
    382     dest4 = strstr(src2, dest2);
    383     printf("strstr string is: %s
    ", dest3);
    384     printf("my_strstr string is: %s
    ", dest4);
    385 //*/
    386 
    387 
    388 
    389 
    390     return 0;
    391 }

     

  • 相关阅读:
    善于倾听,时刻清醒
    FlinkCDC读取MySQL并写入Kafka案例(com.alibaba.ververica)
    直线与圆弧插补采用DDS的模拟程序
    博客园的傻逼程序员开发的傻逼功能
    MeEdu知识付费系统文件上传功能
    微软商业智能(BI)分析服务从入门到精通读书笔记连载
    软件设计师&产品经理应常去的网站
    Windows Phone 7 Jump Start 系列教程
    设计学习《大象》阶段学习总结
    通过FxCop来验证.NET编码规范
  • 原文地址:https://www.cnblogs.com/icefree/p/7646564.html
Copyright © 2011-2022 走看看