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个有效字符复制完成后,再加一个字符串结束符


代码:

 #include <iostream>

 using namespace std;
#define SIZE 100 /***
*char *strcat(dst, src) - concatenate (append) one string to another
*
*Purpose:
* Concatenates src onto the end of dest. Assumes enough
* space in dest.
*
*Entry:
* char *dst - string to which "src" is to be appended
* const char *src - string to be appended to the end of "dst"
*
*Exit:
* The address of "dst"
*
*Exceptions:
*
*******************************************************************************/ //代码写的比较笨拙
//while (*cp++ != '\0');可以用while ( *cp++ );代替
//同样while ( (*cp++ = *src++) != '\0');可用while ( *cp++ = *src++ );代替
char * _strcat_1(char *dst,char *src)
{
if (NULL == dst || NULL == src)
{
return dst;
}
char *cp = dst;
while (*cp++ != '\0');
cp--; //指向'\0' while ( (*cp++ = *src++) != '\0');
//*StrFront = '\0'; //加上字符串结束符,不需要,while结束时,已经加上了结束符
return ( dst );
} //标准库函数给出的implementation
char * _strcat_2(char *dst,const char *src)
{
char *cp = dst; while ( *cp )
cp++; while ( *cp++ = *src++ )
; return ( dst );
} //标准库函数给出的implementation,加上输入合法性检查
//好的implementation要考虑一下几点:
//1)函数src参数应为const,dst参数为非const
//2)注意输入合法性检查
char * _strcat_3(char *dst,const char *src)
{
if (NULL == dst || NULL == src)
{
return dst;
} char *cp = dst; while ( *cp )
cp++; while ( *cp++ = *src++ )
; return ( dst );
}
/***
*char *strncat(front, back, count) - append count chars of back onto front
*
*Purpose:
* Appends at most count characters of the string back onto the
* end of front, and ALWAYS terminates with a null character.
* If count is greater than the length of back, the length of back
* is used instead. (Unlike strncpy, this routine does not pad out
* to count characters).
*
*Entry:
* char *front - string to append onto
* char *back - string to append
* unsigned count - count of max characters to append
*
*Exit:
* returns a pointer to string appended onto (front).
*
*Uses:
*
*Exceptions:
*
*******************************************************************************/ //标准库函数给出的implementation,加上输入合法性检查
//好的implementation要考虑一下几点:
//1)函数src参数应为const,dst参数为非const
//2)注意输入合法性检查
char * _strncat_1(char *dst,const char *src,size_t count)
{
if (NULL == dst || NULL == src)
{
return dst;
} char *cp = dst; while ( *cp )
cp++; /*while ( count-- && *cp++ = *src++ )
;
*/
while ( count-- && (*cp++ = *src++) ) //注意要加括号
; return ( dst );
} //标准库函数的implementation
//_strncat_1可实现与该函数同样的功能,且加入了输入合法性检查
//_strncat_1的写法更为简洁
char * _strncat_2 (
char * front,
const char * back,
size_t count
)
{
char *start = front; while (*front++)
;
front--; //将front指向字符串结束符 while (count--)
if (!(*front++ = *back++)) //在back的长度小于count时,直接返回,此时front已有字符串结束符
return(start); *front = '\0'; //对于back的长度大于count时,加上字符串结束符
return(start);
}
//测试程序
int main()
{
char src_1[SIZE] = "hello ";
char dst_1[SIZE] = "world!";
size_t count = ;
//_strcat
cout<<"test _strcat_1..."<<endl;
cout<<"the dst string is : "<<dst_1<<endl;
cout<<"the src string is : "<<src_1<<endl;
cout<<"the count is : "<<count<<endl;
_strcat_1(dst_1,src_1);
cout<<"the cat result is : "<<dst_1<<endl;
cout<<"(return pointer)the cat result is : "<<_strcat_1(dst_1,src_1)<<endl; cout<<"test _strcat_2..."<<endl;
cout<<"the dst string is : "<<dst_1<<endl;
cout<<"the src string is : "<<src_1<<endl;
cout<<"the count is : "<<count<<endl;
_strcat_2(dst_1,src_1);
cout<<"the cat result is : "<<dst_1<<endl;
cout<<"(return pointer)the cat result is : "<<_strcat_2(dst_1,src_1)<<endl; cout<<"test _strcat_3..."<<endl;
cout<<"the dst string is : "<<dst_1<<endl;
cout<<"the src string is : "<<src_1<<endl;
cout<<"the count is : "<<count<<endl;
_strcat_3(dst_1,src_1);
cout<<"the cat result is : "<<dst_1<<endl;
cout<<"(return pointer)the cat result is : "<<_strcat_3(dst_1,src_1)<<endl; //_strncat_1
char src_2[SIZE] = "happy birthday!";
char dst_2[SIZE] = "baby,";
count = ;
cout<<"test _strncat_1..."<<endl;
cout<<"the dst string is : "<<dst_2<<endl;
cout<<"the src string is : "<<src_2<<endl;
cout<<"the count is : "<<count<<endl;
_strncat_1(dst_2,src_2,count);
cout<<"the cat result is : "<<dst_2<<endl;
cout<<"(return pointer)the cat result is : "<<_strncat_1(dst_2,src_2,count)<<endl; count = ;
cout<<"test _strncat_1..."<<endl;
cout<<"the dst string is : "<<dst_2<<endl;
cout<<"the src string is : "<<src_2<<endl;
cout<<"the count is : "<<count<<endl;
_strncat_1(dst_2,src_2,count);
cout<<"the cat result is : "<<dst_2<<endl;
cout<<"(return pointer)the cat result is : "<<_strncat_1(dst_2,src_2,count)<<endl; //_strncat_2
char src_3[SIZE] = "happy birthday!";
char dst_3[SIZE] = "baby,";
count = ;
cout<<"test _strncat_2..."<<endl;
cout<<"the dst string is : "<<dst_3<<endl;
cout<<"the src string is : "<<src_3<<endl;
cout<<"the count is : "<<count<<endl;
_strncat_1(dst_3,src_3,count);
cout<<"the cat result is : "<<dst_3<<endl;
cout<<"(return pointer)the cat result is : "<<_strncat_1(dst_3,src_3,count)<<endl; count = ;
cout<<"test _strncat_2..."<<endl;
cout<<"the dst string is : "<<dst_3<<endl;
cout<<"the src string is : "<<src_3<<endl;
cout<<"the count is : "<<count<<endl;
_strncat_1(dst_3,src_3,count);
cout<<"the cat result is : "<<dst_3<<endl;
cout<<"(return pointer)the cat result is : "<<_strncat_1(dst_3,src_3,count)<<endl; return ;
}

运行结果:

 test _strcat_1...
the dst string is : world!
the src string is : hello
the count is :
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 :
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 :
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 :
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 :
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 :
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 :
the cat result is : baby,happhapphappy birthday!
(return pointer)the cat result is : baby,happhapphappy birthday!happy birthday!
请按任意键继续. . .

strcat与strncat的C/C++实现的更多相关文章

  1. 字符串函数---strcat()与strncat具体解释及实现

    一.strcat()与strncat() strcat():strcat(dest,src);        strcat把src所指向的字符加入到dest结尾处(覆盖原dest结尾处的'\0').并 ...

  2. c常用函数-strcat 和 strncat

    strcat 和 strncat strcat与strncat都是字符串连接函数,功能上稍有区别: strcat可以把一个字符串的全部内容复制到另一个字符串的后面; strncat则是把一个字符串的指 ...

  3. Linux C 字符串函数 strlen()、strcat()、strncat()、strcmp()、strncmp()、strcpy()、strncpy() 详解

      strlen(返回字符串长度) 表头文件 #include <string.h> 定义函数 size_t strlen(const char *s); 函数说明 strlen()用来计 ...

  4. strcpy、strncpy、strlen、memcpy、memset、strcat、strncat、strcmp、strncmp,strchr

    1.strcpy #include<stdio.h> #include<assert.h> char *mystrcpy(char *dest, const char *src ...

  5. C语言 - strcat和strncat的编程实现及总结

    一.函数strcat与stcncat的函数实现 1.strcat函数的实现 要求: 原型:char * strcat(char *dest, const char *src);    头文件:#inc ...

  6. Linux C 收藏

    某招聘要求:熟悉高性能分布式网络服务端设计开发,熟悉epoll.多线程.异步IO.事件驱动等服务端技术: <UNIX环境高级编程(第3版)>apue.h等源码文件的编译安装 <UNI ...

  7. Linux C编程(1) vim及gcc命令

    1. 输入以下命令可以启动vi:      (1) vi:不指定文件名,在保存文件时需要指定文件名.      (2) vi 文件名:该文件既可以是已存在的,也可以是新建的.      (3) vi ...

  8. LoadRunner中截取字符串

    LoadRunner中截取字符串 /*strchr和strrchr的区别*/ char *strTest1="citms citms"; char *strTest2,*strTe ...

  9. char[] 操作

    字符串的初始化方法1.char str[10] = { 'H', 'e', 'l', 'l', 'o', '\0' };2.char str[10] = "Hello";   ch ...

随机推荐

  1. TweenMax动画库学习(六)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  2. 数据库降级-从sqlserver 2008 降到 2005

    前天遇到一个问题,是一个数据库是Sqlserver 2008的,而平台数据库库是2005的,需要把2008的数据库附加进来,试了很多办法,现在觉得最好的办法就是导出导入办法. 第一步 新建一个Sqls ...

  3. jQuery 图片轮播的代码分离

    以前遇到过jQuery实现列表自动滚动,这次的图片轮播在原理上与之相同,只有一些细微的差别,就是需要在图片的右下角显示当前图片的序号. html代码,以及对应的css代码: <div id=&q ...

  4. js中的计时器

    在JS中做二级菜单时,被一个鼠标移出时隐藏的小问题困扰了很久. <script> function Menu(id){ var _this=this; this.obj=document. ...

  5. 代码规范-IAR设置

    1.在IAR内定义 char 2. 去掉相关的告警 3.LANGUAGE设置

  6. poj 2947 Widget Factory

    Widget Factory 题意:有n件装饰品,有m组信息.(1 <= n ,m<= 300)每组信息有开始的星期和结束的星期(是在mod 7范围内的)并且还包括num种装饰品的种类(1 ...

  7. Memcache 分布式解决方案 之 : 普通 Hash 分布

    <?php /* mhash * 其实说白了,就是为了实现返回0或1 */ function mmhash($key){ $md5 = substr(md5($key),0,8);//取该字符串 ...

  8. 【BZOJ 1088】 [SCOI2005]扫雷Mine

    Description 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没 ...

  9. 防止IFRAME页被嵌套

    防止IFRAME页被嵌套 //最大化窗口,防止窗口嵌套 if (parent.location != window.location){ parent.location = window.locati ...

  10. PAT-乙级-1018. 锤子剪刀布 (20)

    1018. 锤子剪刀布 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 大家应该都会玩“锤子剪刀布”的游 ...