zoukankan      html  css  js  c++  java
  • strcat与strncat的C/C++实现

    2013-07-05 15:47:19

    本函数给出了几种strcat与strncat的实现,有ugly implementation,也有good implementation。并参考标准库中的implementation,最后给出了比较好的implementation。

    注意以下几点:

    对于while (*cp++),要注意循环结束时,指针指向的位置是否是预期的,如下面的:

     while ( *cp )
      cp++;

    while (*cp++)
      ;
     cp--;   

    的效果是一样的。

    在第二种写法中就要注意在结束循环后,对cp减1,才能指向字符串结束符的位置。

    while (*cp++ != '');可以用while ( *cp++ );代替

    同样while ( (*cp++ = *src++) != '');可用while ( *cp++ = *src++ );代替

    _strncat_1可实现与标准库函数即_strncat_2同样的功能,可以使得在count大于、小于以及等于source长度时,加上字符串结束符,且加入了输入合法性检查;但_strncat_1的写法更为简洁

    小结:

    标准库函数并没有输入合法性检查,这将输入合法性检查的任务推给了函数的调用者。
    对于strcat函数,好的implementation要考虑一下几点:

      1. 函数src参数应为const,dst参数为非const,count为size_t类型;
      2. 函数要返回dst的地址,以方便嵌套使用该函数;
      3. 确定dst要有字符串结束符;
      4. 注意输入合法性检查注意输入合法性检查。

    对于strncpy函数,除了以上几点外,好的implementation还要考虑:

    当source的长度小于count时,应该怎么办?

    标准库函数的做法是,将source的所有有效字符复制完成后,再加一个字符串结束符;当source的长度大于火等于count时,将source的count个有效字符复制完成后,再加一个字符串结束符


    代码:

      1 #include <iostream>
      2 
      3 using namespace std;
      4 #define SIZE 100
      5 
      6 /***
      7 *char *strcat(dst, src) - concatenate (append) one string to another
      8 *
      9 *Purpose:
     10 *       Concatenates src onto the end of dest.  Assumes enough
     11 *       space in dest.
     12 *
     13 *Entry:
     14 *       char *dst - string to which "src" is to be appended
     15 *       const char *src - string to be appended to the end of "dst"
     16 *
     17 *Exit:
     18 *       The address of "dst"
     19 *
     20 *Exceptions:
     21 *
     22 *******************************************************************************/
     23 
     24 //代码写的比较笨拙
     25 //while (*cp++ != '');可以用while ( *cp++ );代替
     26 //同样while ( (*cp++ = *src++) != '');可用while ( *cp++ = *src++ );代替
     27 char * _strcat_1(char *dst,char *src)  
     28 {
     29     if (NULL == dst || NULL == src)
     30     {
     31         return dst;
     32     }
     33     char *cp = dst;
     34     while (*cp++ != '');
     35     cp--;                //指向''
     36     
     37     while ( (*cp++ = *src++) != '');
     38     //*StrFront = '';    //加上字符串结束符,不需要,while结束时,已经加上了结束符
     39     return ( dst );
     40 }
     41 
     42 //标准库函数给出的implementation
     43 char * _strcat_2(char *dst,const char *src)  
     44 {
     45     char *cp = dst;
     46 
     47     while ( *cp )
     48         cp++;
     49 
     50     while ( *cp++ = *src++ )
     51         ;
     52     
     53     return ( dst );
     54 }
     55 
     56 //标准库函数给出的implementation,加上输入合法性检查
     57 //好的implementation要考虑一下几点:
     58 //1)函数src参数应为const,dst参数为非const
     59 //2)注意输入合法性检查
     60 char * _strcat_3(char *dst,const char *src)  
     61 {
     62     if (NULL == dst || NULL == src)
     63     {
     64         return dst;
     65     }
     66 
     67     char *cp = dst;
     68 
     69     while ( *cp )
     70         cp++;
     71 
     72     while ( *cp++ = *src++ )
     73         ;
     74 
     75     return ( dst );
     76 }
     77 /***
     78 *char *strncat(front, back, count) - append count chars of back onto front
     79 *
     80 *Purpose:
     81 *       Appends at most count characters of the string back onto the
     82 *       end of front, and ALWAYS terminates with a null character.
     83 *       If count is greater than the length of back, the length of back
     84 *       is used instead.  (Unlike strncpy, this routine does not pad out
     85 *       to count characters).
     86 *
     87 *Entry:
     88 *       char *front - string to append onto
     89 *       char *back - string to append
     90 *       unsigned count - count of max characters to append
     91 *
     92 *Exit:
     93 *       returns a pointer to string appended onto (front).
     94 *
     95 *Uses:
     96 *
     97 *Exceptions:
     98 *
     99 *******************************************************************************/
    100 
    101 //标准库函数给出的implementation,加上输入合法性检查
    102 //好的implementation要考虑一下几点:
    103 //1)函数src参数应为const,dst参数为非const
    104 //2)注意输入合法性检查
    105 char * _strncat_1(char *dst,const char *src,size_t count)  
    106 {
    107     if (NULL == dst || NULL == src)
    108     {
    109         return dst;
    110     }
    111 
    112     char *cp = dst;
    113 
    114     while ( *cp )    
    115         cp++;
    116 
    117     /*while ( count-- && *cp++ = *src++ )
    118         ; 
    119 */
    120     while ( count-- && (*cp++ = *src++) )  //注意要加括号
    121         ; 
    122 
    123     return ( dst );
    124 }
    125 
    126 //标准库函数的implementation
    127 //_strncat_1可实现与该函数同样的功能,且加入了输入合法性检查
    128 //_strncat_1的写法更为简洁
    129 char *  _strncat_2 (
    130     char * front,
    131     const char * back,
    132     size_t count
    133     )
    134 {
    135     char *start = front;
    136 
    137     while (*front++)
    138         ;
    139     front--;     //将front指向字符串结束符
    140 
    141     while (count--)
    142         if (!(*front++ = *back++))  //在back的长度小于count时,直接返回,此时front已有字符串结束符
    143             return(start);
    144 
    145     *front = '';   //对于back的长度大于count时,加上字符串结束符
    146     return(start);
    147 }
    148 //测试程序
    149 int main()
    150 {
    151     char src_1[SIZE] = "hello ";
    152     char dst_1[SIZE] = "world!";
    153     size_t count = 4;
    154     //_strcat
    155     cout<<"test _strcat_1..."<<endl;
    156     cout<<"the dst string is : "<<dst_1<<endl;
    157     cout<<"the src string is : "<<src_1<<endl;
    158     cout<<"the count is : "<<count<<endl;
    159     _strcat_1(dst_1,src_1);
    160     cout<<"the cat result is : "<<dst_1<<endl;
    161     cout<<"(return pointer)the cat result is : "<<_strcat_1(dst_1,src_1)<<endl;
    162 
    163     cout<<"test _strcat_2..."<<endl;
    164     cout<<"the dst string is : "<<dst_1<<endl;
    165     cout<<"the src string is : "<<src_1<<endl;
    166     cout<<"the count is : "<<count<<endl;
    167     _strcat_2(dst_1,src_1);
    168     cout<<"the cat result is : "<<dst_1<<endl;
    169     cout<<"(return pointer)the cat result is : "<<_strcat_2(dst_1,src_1)<<endl;
    170 
    171     cout<<"test _strcat_3..."<<endl;
    172     cout<<"the dst string is : "<<dst_1<<endl;
    173     cout<<"the src string is : "<<src_1<<endl;
    174     cout<<"the count is : "<<count<<endl;
    175     _strcat_3(dst_1,src_1);
    176     cout<<"the cat result is : "<<dst_1<<endl;
    177     cout<<"(return pointer)the cat result is : "<<_strcat_3(dst_1,src_1)<<endl;
    178 
    179     //_strncat_1
    180     char src_2[SIZE] = "happy birthday!";
    181     char dst_2[SIZE] = "baby,";
    182     count = 4;
    183     cout<<"test _strncat_1..."<<endl;
    184     cout<<"the dst string is : "<<dst_2<<endl;
    185     cout<<"the src string is : "<<src_2<<endl;
    186     cout<<"the count is : "<<count<<endl;
    187     _strncat_1(dst_2,src_2,count);
    188     cout<<"the cat result is : "<<dst_2<<endl;
    189     cout<<"(return pointer)the cat result is : "<<_strncat_1(dst_2,src_2,count)<<endl;
    190 
    191     count = 30;
    192     cout<<"test _strncat_1..."<<endl;
    193     cout<<"the dst string is : "<<dst_2<<endl;
    194     cout<<"the src string is : "<<src_2<<endl;
    195     cout<<"the count is : "<<count<<endl;
    196     _strncat_1(dst_2,src_2,count);
    197     cout<<"the cat result is : "<<dst_2<<endl;
    198     cout<<"(return pointer)the cat result is : "<<_strncat_1(dst_2,src_2,count)<<endl;
    199 
    200     //_strncat_2
    201     char src_3[SIZE] = "happy birthday!";
    202     char dst_3[SIZE] = "baby,";
    203     count = 4;
    204     cout<<"test _strncat_2..."<<endl;
    205     cout<<"the dst string is : "<<dst_3<<endl;
    206     cout<<"the src string is : "<<src_3<<endl;
    207     cout<<"the count is : "<<count<<endl;
    208     _strncat_1(dst_3,src_3,count);
    209     cout<<"the cat result is : "<<dst_3<<endl;
    210     cout<<"(return pointer)the cat result is : "<<_strncat_1(dst_3,src_3,count)<<endl;
    211 
    212     count = 30;
    213     cout<<"test _strncat_2..."<<endl;
    214     cout<<"the dst string is : "<<dst_3<<endl;
    215     cout<<"the src string is : "<<src_3<<endl;
    216     cout<<"the count is : "<<count<<endl;
    217     _strncat_1(dst_3,src_3,count);
    218     cout<<"the cat result is : "<<dst_3<<endl;
    219     cout<<"(return pointer)the cat result is : "<<_strncat_1(dst_3,src_3,count)<<endl;
    220 
    221     return 0;
    222 }

    运行结果:

     test _strcat_1...
    the dst string is : world!
    the src string is : hello
    the count is : 4
    the cat result is : world!hello
    (return pointer)the cat result is : world!hello hello
    test _strcat_2...
    the dst string is : world!hello hello
    the src string is : hello
    the count is : 4
    the cat result is : world!hello hello hello
    (return pointer)the cat result is : world!hello hello hello hello
    test _strcat_3...
    the dst string is : world!hello hello hello hello
    the src string is : hello
    the count is : 4
    the cat result is : world!hello hello hello hello hello
    (return pointer)the cat result is : world!hello hello hello hello hello hello
    test _strncat_1...
    the dst string is : baby,
    the src string is : happy birthday!
    the count is : 4
    the cat result is : baby,happ
    (return pointer)the cat result is : baby,happhapp
    test _strncat_1...
    the dst string is : baby,happhapp
    the src string is : happy birthday!
    the count is : 30
    the cat result is : baby,happhapphappy birthday!
    (return pointer)the cat result is : baby,happhapphappy birthday!happy birthday!
    test _strncat_2...
    the dst string is : baby,
    the src string is : happy birthday!
    the count is : 4
    the cat result is : baby,happ
    (return pointer)the cat result is : baby,happhapp
    test _strncat_2...
    the dst string is : baby,happhapp
    the src string is : happy birthday!
    the count is : 30
    the cat result is : baby,happhapphappy birthday!
    (return pointer)the cat result is : baby,happhapphappy birthday!happy birthday!
    请按任意键继续. . .
  • 相关阅读:
    [转载]Python爬虫之xpath使用技巧
    手机自动化脚本
    英镑像素转换
    小程序路径存入数据库
    avalonia项目在银河麒麟操作系统arm架构上运行报错:default font family is not be null or empty
    http 301、304状态码
    一文完全理解IP
    TCP是如何保证可靠传输的?
    一文弄懂TCP常见面试题
    一文弄懂HTTP常见面试题
  • 原文地址:https://www.cnblogs.com/youngforever/p/3173880.html
Copyright © 2011-2022 走看看