strstr strcpy 函数的实现
实现 函数 strstr strcpy
2023-09-27 14:25:21 时间
一. strcpy
代码实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <assert.h> #include <iostream> //#include <string.h> using namespace std; int strlen(const char *src) { assert(src != NULL); int lens = 0; while (*src++ != '\0') lens++; return lens; } char *memcpy(char *dst, const char *src, int cnt) { assert(dst != NULL && src != NULL); char *ret = dst; if (dst >= src && dst <= src + cnt - 1) { src += cnt - 1; dst += cnt - 1; while (cnt--) *dst-- = *src--; } else { while (cnt--) *dst++ = *src++; } return ret; } char *strcpy(char *dst, const char *src) { assert(dst != NULL); assert(src != NULL); char *ret = dst; memcpy(dst, src, strlen(src)+1); return ret; } int main() { char a[] = "hello"; char b[] = "b1"; //strcpy(a, b); strcpy(a, a+1); char *f = strcpy(a, a+1); cout << a << endl; cout << f << endl; int m = 0; int n = 5; int c = (m=n++); cout << "c:" << c << endl; cout << "n:" << n << endl; return 0; }
已知strcpy函数的原型是:
char *strcpy(char *dst, const char *src);
- 实现strcpy函数
- 解释为什么要返回char *
- 假如考虑dst和src内存重叠的情况,strcpy该怎么实现
1.strcpy的实现代码
char * strcpy(char *dst,const char *src) //[1]
{
assert(dst != NULL && src != NULL); //[2]
char *ret = dst; //[3]
while ((*dst++=*src++)!='\0'); //[4]
return ret;
}
[1]const修饰
- 源字符串参数用const修饰,防止修改源字符串。
[2]空指针检查
- 不检查指针的有效性,说明答题者不注重代码的健壮性。
- 检查指针的有效性时使用assert(!dst && !src);char *转换为bool即是类型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。
- 检查指针的有效性时使用assert(dst != 0 && src != 0);直接使用常量(如本例中的0)会减少程序的可维护性。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。
[3]返回目标地址
- 忘记保存原始的strdstt值。
[4]'\0'
- 循环写成while (*dst++=*src++);明显是错误的。
- 循环写成while (*src!='\0') *dst++=*src++;
循环体结束后,dst字符串的末尾没有正确地加上'\0'。
2.为什么要返回char *?
返回dst的原始值使函数能够支持链式表达式。
链式表达式的形式如:
int l=strlen(strcpy(strA,strB));
又如:
char * strA=strcpy(new char[10],strB);
返回strSrc的原始值是错误的。
其一,源字符串肯定是已知的,返回它没有意义。
其二,不能支持形如第二例的表达式。
其三,把const char *作为char *返回,类型不符,编译报错。
3.假如考虑dst和src内存重叠的情况,strcpy该怎么实现
char s[10]="hello";
strcpy(s, s+1); //应返回ello,
//strcpy(s+1, s); //应返回hhello,但实际会报错,因为dst与src重叠了,把'\0'覆盖了
所谓重叠,就是src未处理的部分已经被dst给覆盖了,只有一种情况:src<=dst<=src+strlen(src)
C函数memcpy自带内存重叠检测功能,下面给出memcpy的实现my_memcpy。
char * strcpy(char *dst,const char *src)
{
assert(dst != NULL && src != NULL);
char *ret = dst;
my_memcpy(dst, src, strlen(src)+1);
return ret;
}
my_memcpy的实现如下
char *my_memcpy(char *dst, const char* src, int cnt) { assert(dst != NULL && src != NULL); char *ret = dst; if (dst >= src && dst <= src+cnt-1) //内存重叠,从高地址开始复制 { dst = dst+cnt-1; src = src+cnt-1; while (cnt--) *dst-- = *src--; } else //正常情况,从低地址开始复制 { while (cnt--) *dst++ = *src++; } return ret; }
二. strstr实现
char * strstr(const char *s1, const char *s2) { if (s2 != NULL) { while (*s1 != '\0') { for (int i = 0; *(s1 + i) == *(s2 + i); ++i) { if (*(s2 + i + 1) == '\0') return (char *)s1; } s1++; } return NULL; } else return (char *)s1; } int main() { char str[] = "12345abc"; char *p = strstr(str, "abc"); printf ("%s\n", p); }
s
相关文章
- 一个简单的java回调函数的实现
- Google Earth Engine(GEE)——利用光谱距离函数实现滑坡监测以sentinel-2数据为例
- Java利用正则表达式实现中英文日期转换函数封装
- OpenCV的图像直角坐标系转极坐标系的函数warpPolar()详解,并附自己写的实现直角坐标系转极坐标系的MATLAB代码
- 利用OpenCV的flip()函数实现图像的水平镜像(水平翻转)、垂直镜像(垂直翻转)
- 半阈值化的原理、作用及利用函数OpenCV的函数threshold()实现半阈值化的方法
- Python的Numpy库的函数astype()在将大范围数据类型转换为小范围数据类型时并不是做饱和(saturate)操作(附实现饱和操作的方法)
- java实现23种设计模式-策略者模式
- JS leetcode 实现strStr()函数 题解分析
- 使用函数指针实现父类函数调用子类函数的两种方式
- Flutter中实现视图、功能和样式代码的分离(使用mixin与扩展函数)
- bind函数作用、应用场景以及模拟实现
- python中实现排序list
- opencv2函数学习之threshold:实现图像阈值化
- Excel VLOOKUP实用教程之 04 vlookup如何实现三变量查找,三个条件字段查询数据?(教程含数据excel)
- 生产者-消费者模型(自定义类 与函数 2种实现方式)
- 《敏捷可执行需求说明 Scrum提炼及实现技术》—— 2.7 验证“可能存在”的假设
- Vue3+elementplus搭建通用管理系统实例十一:动态表单及详情页实现下
- 知道用户的坐标和商家坐标,获取查询附近商家的实现
- capybara5--实现你第一个自动化场景
- 【HarmonyOS】【ARK UI】怎么实现一个悬浮框
- 外部类委托内部类变相实现多继承
- Python实现空间直角坐标转高斯克吕格平面坐标
- atoi()函数的实现
- 【图像处理】——Python+opencv实现二值图像的轮廓边界跟踪以及轮廓面积周长的求解(findcontours函数和contourArea函数)
- winform窗体应用实现淡入淡出等效果
- Python实现全排列(回调函数方式)
- flex应用:使用flex布局实现纯CSS树状图表