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!
请按任意键继续. . .

strcat与strncat的C/C++实现相关推荐

  1. C语言——数组、字符串处理函数、strlen、strcpy和strncpy、strcat和strncat、strcmp和strncmp

    目录 一.数组 1.定义:类型 数组名[元素个数] 2.数组不能动态定义 3.如何访问数组中的元素:数组名[下标] 4.循环与数组的关系 5.数组的初始化 二.C99标准中的数组 三.字符串处理函数 ...

  2. C语言strcat、strncat函数详解

    C语言strcat.strncat函数详解 一.strcat函数 1.函数原型 2.函数参数.返回值解析 3.函数作用 4.注意事项 5.strcat函数模拟实现 二.strncat函数 1.函数原型 ...

  3. strcat和strncat的区别及原理

    我们都知道strcat和strncat都是在一个字符串后追加字符的函数,那t它们有什么区别呢?它们又是什么原理呢? 首先要了解二者的原理才能够区分它们有什么样的区别: strcat的用法--调用str ...

  4. C语言之strcat和strncat

    C语言之strcat和strncat strcat为连接函数,其作用是把2个字符串连接为一个,strncat函数可以指定其后连接的字符串的个数. 代码示例:(strcat函数) /* strcat 和 ...

  5. C语言模拟实现strcat,strncat函数

    追加函数strcat char *strcat(char *strDestination, const char *strSource); 实现思路:在目标函数中找到元素为0的位置,将source字符 ...

  6. C语言学习笔记---字符串拼接函数 strcat() 和 strncat()

    strcat()函数    strcat()函数主要用来拼接字符串,用于将一个字符串拼接到另一个字符串的后面.下面通过一个简单的例子来演示一下这个函数的使用方法. int main() {char s ...

  7. strlen函数在哪个头文件_第二十七中、字符串处理函数-strlen、strcat、strncat

    接下来几章我们来了解下常用的字符串处理函数,要使用这些函数需要引入头文件string.h. 1. strlen函数 strlen函数可以得到字符串的实际长度.它的函数原型是: size_t strle ...

  8. strcat函数 strncat函数

    函数原型:extern char *strcat(char *dest,char *src) 参数说明:dest为一个目的字符串的指针,即被连接的字符串(在前),src为一个源字符串的指针(在后). ...

  9. 【C语言】strcat、strncat详解并模拟实现

    1.库函数strcat:  函数声明:char* strcat(char* strdestination, const char* strsource); 提示:源字符串在函数实现过程中不修改其内容, ...

最新文章

  1. Yahoo网站性能优化的34条军规
  2. 天线的近场区和远场区
  3. TCP为什么是3次握手?
  4. Java中MessageFormat的使用
  5. 成功解决No such file or directory: site-packages\\pyyaml-5.3-py3.6-win-amd64.egg\\EGG-INFO\\top_level.t
  6. RocksDB 6.0.2 发布,Facebook 推出的存储系统
  7. 就编程而言,可移植性意味着什么?
  8. java插入数据库字符串拼接_java中PreparedStatement解决需转义字符向数据库中插入时的转义问题 | 学步园...
  9. Android Gallery组件实现循环显示图像
  10. js实现审批流_小程序瀑布流组件:支持翻页与图片懒加载
  11. Linux使用socket选项的定时器
  12. Scala学习笔记总结
  13. Maximum call stack size exceeded 如何解决?
  14. 暴风激活工具,劫持Chrome浏览器主页
  15. win7语言文件夹c盘什么位置,Win7系统C盘中ProgramData文件夹在哪?
  16. Docker 加速器
  17. 织梦后台界面修改方法
  18. Asciinema - 终端日志记录神器,机器学习开发者的福音
  19. 安装和配置PhysX
  20. 语音信号处理-第三方库:librosa、nnAudio、torchAudio三者的差异

热门文章

  1. JS控制文字只显示两行,超出部分显示省略号
  2. 数字展示领域该这样用 沉浸式方案应用解读
  3. 开源 免费 java CMS - FreeCMS1.5-数据对象-guestbook
  4. struts2+spring+mybatis简单配置
  5. SQL 2008镜像配置
  6. 探测远程主机操作系统指纹的全新技术
  7. Linux 进程虚拟地址空间布局
  8. Luogu P2827 蚯蚓
  9. BZOJ2843 极地旅行社 LCT
  10. 5.18下午 口语课 阅读