strcat与strncat的C/C++实现
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个有效字符复制完成后,再加一个字符串结束符
代码:
#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++实现的更多相关文章
- 字符串函数---strcat()与strncat具体解释及实现
一.strcat()与strncat() strcat():strcat(dest,src); strcat把src所指向的字符加入到dest结尾处(覆盖原dest结尾处的'\0').并 ...
- c常用函数-strcat 和 strncat
strcat 和 strncat strcat与strncat都是字符串连接函数,功能上稍有区别: strcat可以把一个字符串的全部内容复制到另一个字符串的后面; strncat则是把一个字符串的指 ...
- Linux C 字符串函数 strlen()、strcat()、strncat()、strcmp()、strncmp()、strcpy()、strncpy() 详解
strlen(返回字符串长度) 表头文件 #include <string.h> 定义函数 size_t strlen(const char *s); 函数说明 strlen()用来计 ...
- 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 ...
- C语言 - strcat和strncat的编程实现及总结
一.函数strcat与stcncat的函数实现 1.strcat函数的实现 要求: 原型:char * strcat(char *dest, const char *src); 头文件:#inc ...
- Linux C 收藏
某招聘要求:熟悉高性能分布式网络服务端设计开发,熟悉epoll.多线程.异步IO.事件驱动等服务端技术: <UNIX环境高级编程(第3版)>apue.h等源码文件的编译安装 <UNI ...
- Linux C编程(1) vim及gcc命令
1. 输入以下命令可以启动vi: (1) vi:不指定文件名,在保存文件时需要指定文件名. (2) vi 文件名:该文件既可以是已存在的,也可以是新建的. (3) vi ...
- LoadRunner中截取字符串
LoadRunner中截取字符串 /*strchr和strrchr的区别*/ char *strTest1="citms citms"; char *strTest2,*strTe ...
- char[] 操作
字符串的初始化方法1.char str[10] = { 'H', 'e', 'l', 'l', 'o', '\0' };2.char str[10] = "Hello"; ch ...
随机推荐
- js-shortid:优雅简洁地实现短ID
短ID在实际运用中很广泛, 其中比较典型的运用就是短地址. 市面上肯定有不少开源的生成短ID库, 基于node.js的估计也不少. 鉴于本人已然是node.js的脑残粉(本职java开发), 很多业余 ...
- c# 判断点是否在区域内 点在区域内 在多边形内 判断
方法一 算法 : public int isLeft(Point P0, Point P1,Point P2) { int abc= ((P1.X - P0.X) ...
- 由底层和逻辑说开去——c++之类与对象的深入剖析
类是什么,对象是什么, 这两个问题在各个c++书里面都以一种抽象的描述方式,给了我们近乎完美的答案,然后我好像就知道什么是类什么是对象了,但是当扪心自问,类在哪儿,对象在哪儿,成员方法在哪儿,成员变 ...
- EXTJS API
EXTJS API 链接: http://docs.sencha.com/extjs/5.0.0/ http://docs.sencha.com/extjs/4.2.2/ http://docs.se ...
- 洛谷 P1858 多人背包
求01背包前k优解的价值和 输入输出格式 Input/output 输入格式:第一行三个数K.V.N(k<=50,v<=5000,n<=200)接下来每行两个数,表示体积和价值输出格 ...
- webx学习笔记
Webx学习笔记周建旭 2014-08-01 Webx工作流程 图 3.2. Webx Framework如何响应请求 当Webx Framework接收到一个来自WEB的请求以后,实际上它主要做了两 ...
- linux内核分析之内存管理
1.struct page /* Each physical page in the system has a struct page associated with * it to keep tra ...
- 怎样修改Windows7环境变量
在使用电脑的时候要运行某些特定的应用程序时需要修改系统的环境变量,例如安装JAVA时我们就需要配置系统的环境变量.那什么是环境变量呢?环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,比 ...
- Microsoft .NET Framework 4.0安装时发生严重错误 无法安装
前几天安装Axure,电脑提示没有安装.NET Framework4.0,然后下载安装,又提示如下图所示情况: 在网上找了好多方法,大多都是打开cmd,输入net stop WuAuServ,修改注册 ...
- 分析Hibernate的事务处理机制
Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的 Transaction实际上是底层的JDBC Transactio ...