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. T-SQL实例 函数结果设置为列别名

    本文分享一个T-SQL的例子,将自定义函数的结果作为别名列,是个不错的应用实例,有兴趣的朋友研究下. T-SQL实例,学习下将函数结果作为别名列的方法. 代码: view source print? ...

  2. 有关linux日志分析的详细介绍

    linux的日志文件可以帮助我们了解系统所处的状态,比如查出哪些用户有登入,及其它安全相关的一些问题. linux下的日志分析. 以下内容,部分参考了:探讨 linux 日志分析 这篇文章. 1.了解 ...

  3. Dapper.ColumnMapper 的使用

    using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; usin ...

  4. json 语义分析

    json 中:元素与值用冒号 ":" 隔开元素与元素用逗号 "," 隔开{} 之间是一个对象, 对象可以层层嵌套[] 表示数组, 数组元素用逗号 ", ...

  5. Demo学习: FileUpload

    FileUpload 文件上传,学习TUniFileUpload控件的使用 TUniFileUpload主要属性: Filter: 文件类型过滤,这个属性在web模式下是无效的,UniGUI目前版本还 ...

  6. Django Admin后台使用tinymc 富文本编辑器

    1.CDN地址 <script src="//cdn.tinymce.com/4/tinymce.min.js"></script> 2.修改base.ht ...

  7. Have Fun with Numbers (大数)

    Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, wit ...

  8. nginx+php-fpm 502 bad gateway

    输出日志配置: http://blog.csdn.net/wzy_1988/article/details/8486888 解决方案: http://www.cnblogs.com/jackluo/p ...

  9. Maven使用本地jar包(小私服?支持自动打入war包)

    1.库目录结构 D:\maven-local-repo\cn\xcf007\MD5\1.0\MD5-1.0.jar 2.安装到该本地库 mvn install:install-file -Dfile= ...

  10. PS 颜色表大全-颜色中文名(1)

    颜色中文名  鸨色#f7acbc 赤白橡#deab8a 油色#817936 绀桔梗#444693 踯躅色#ef5b9c 肌色#fedcbd 伽罗色#7f7522 花色#2b4490 桜色#feeeed ...