strcat与strncat的C/C++实现

转载 https://www.cnblogs.com/youngforever/p/3173880.html
本函数给出了几种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要考虑一下几点:

函数src参数应为const,dst参数为非const,count为size_t类型;
函数要返回dst的地址,以方便嵌套使用该函数;
确定dst要有字符串结束符;
注意输入合法性检查注意输入合法性检查。
对于strncpy函数,除了以上几点外,好的implementation还要考虑:

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

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

代码:

复制代码
1 #include
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!
请按任意键继续. . .
复制代码

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值