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要考虑一下几点:
-
- 函数src参数应为const,dst参数为非const,count为size_t类型;
- 函数要返回dst的地址,以方便嵌套使用该函数;
- 确定dst要有字符串结束符;
- 注意输入合法性检查注意输入合法性检查。
对于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! 请按任意键继续. . .