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++ != '\0');可以用while ( *cp++ );代替

同样while ( (*cp++ = *src++) != '\0');可用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++ != '\0');可以用while ( *cp++ );代替
 26 //同样while ( (*cp++ = *src++) != '\0');可用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++ != '\0');
 35     cp--;                //指向'\0'
 36     
 37     while ( (*cp++ = *src++) != '\0');
 38     //*StrFront = '\0';    //加上字符串结束符,不需要,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 = '\0';   //对于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!
请按任意键继续. . .

 

posted @ 2013-07-05 16:06  永不止步,永无止境  阅读(2776)  评论(0编辑  收藏  举报