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. C#语言的Image和byte数组的互相转换

    /// <summary> /// 字节数组转换为图片 /// </summary> /// <param name="buffer">字节数组 ...

  2. Web前端的35个jQuery小技巧

    1. 禁止右键点击 $(document).ready(function(){     $(document).bind("contextmenu",function(e){   ...

  3. Clone table header and set as the first element, and replace header's th with td

    Clone table header and replace header's th with td var tableHeaderRow = '#tableId tbody tr:nth-child ...

  4. php正确解码javascript中通过escape编码后的字符

    js的escape如何在PHP中来解呢? 下面的这个函数可以正确的解析,网上有不少unescape的函数,但好用的不多. 这是很久以前收集的一个,不知道谁写的了,但经过测试没有问题~ function ...

  5. Spark Streaming揭秘 Day22 架构源码图解

    Spark Streaming揭秘 Day22 架构源码图解 今天主要是通过图解的方式,对SparkStreaming的架构进行一下回顾. 下面这个是其官方标准的流程描述. SparkStreamin ...

  6. scala知识点(一)

    1.drop,dropRight,dropWhile drop: drop(n: Int): List[A] 丢弃前n个元素,返回剩下的元素 dropRight: dropRight(n: Int): ...

  7. try、catch、finally的使用分析---与 return 相关

    看了一篇文章,讲解的是关于java中关于try.catch.finally中一些问题 下面看一个例子(例1),来讲解java里面中try.catch.finally的处理流程   1 2 3 4 5 ...

  8. PyQt4学习记录之事件和信号

    事件是任何 GUI程序中很重要的部分.所有 Python GUI 应用都是事件驱动的.一个应用对其生命期产生的不同的事件类型做出反应.事件是主要由应用的用户产生.但是,也可以通过其他方法产生,比如,网 ...

  9. 1021.Deepest Root (并查集+DFS树的深度)

    A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...

  10. 通过 struct 成员地址 获取 struct 结构体地址

    1. 问题描述: 现在定义了一个结构体: struct Foo { int a; int b; }; Foo foo; 假如由于函数传参等原因,现在程序只能拿到 foo.b 的地址,这时想通过某种方法 ...