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 ...
随机推荐
- 终于解决了我的DISCUZ 无法连接到您的服务器,可能您的服务器处于防火墙后端 论坛云平台的问题~
事由:由于前几天折腾备份,将论坛源文件误删了大部分,于是我重新下载了源码,传到了空间. 然后问题来了,我关闭纵横搜索提示“无法连接到您的服务器,可能您的服务器处于防火墙后端”,设置纵横搜索页一直显示“ ...
- DTCMS自定义标签:面包屑导航,栏目中通过栏目调用名称获得栏目名称
DTcms.Web.UI\Label\category.cs中增加标签 /// <summary> /// 自定义:通过类别name获得类别title /// </summary&g ...
- preventDefault()、stopPropagation()、return false 之间的区别
“return false”之所以被误用的如此厉害,是因为它看起来像是完成了我们交给它的工作,浏览器不会再将我们重定向到href中的链接,表单也不会被继续提交,但这么做到底有什么不对呢? 可能在你刚开 ...
- 教你配置linux服务器登陆欢迎信息
登录一台测试机时发现显示PS1前还显了一行’Welcome to Cloudex’的欢迎信息,真丫牛B.在linux中,设置/etc/issue和/etc/motd文件即可实现这样的登录欢迎信息. 登 ...
- ECSHOP 商品页详情页 添加同类随机商品
1,根目录下找到goods.php文件 找到代码 $smarty->assign('properties', $properties['pro']); ...
- Spark Streaming揭秘 Day25 StreamingContext和JobScheduler启动源码详解
Spark Streaming揭秘 Day25 StreamingContext和JobScheduler启动源码详解 今天主要理一下StreamingContext的启动过程,其中最为重要的就是Jo ...
- hadoop中遇到的问题。
1.物理主机中无法访问管理界面,在虚拟主机中可以访问, 这跟防火墙有关系,重启一下防火墙,然后关闭,最后重启一下handoop,应该就可以了!!!!(hadoop首战顺利!!!!!(●'◡'●))
- Matlab删除NaN数据
删除包含NaN的行: a(any(isnan(a), 2),:) = []; 删除全部为NaN的行: a(all(isnan(a), 2),:) = [];
- 【BZOJ 1053】[HAOI2007]反素数ant
Description 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例如,整数1 ...
- C# Windows - ListBox&CheckedListBox
ListBox和CheckedListBox类的属性 属性 说明 SelectedIndex 这个值表明列表框中选中项的基于0的索引 ColumnWidth 在包含多个列的列表框中,这个属性指定列宽 ...