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要考虑一下几点:
对于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!
请按任意键继续. . .
原文链接: https://www.cnblogs.com/youngforever/p/3173880.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/94676
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!