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!
請按任意鍵繼續. . .
複製代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章