模拟实现 strcpy strcat strstr strcmp 函数

本文介绍了C语言中四个重要的字符串处理函数:strcpy、strcat、strstr和strcmp的实现原理及代码。通过阅读,你可以理解这些函数如何处理字符串拷贝、连接、查找和比较,并提供了相应的函数实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

strcap 函数说明:msdn 中对该函数函数原型和返回值的描述为: 函数原型: char *strcpy( char *strDestination, const char *strSource );返回值:Each of these functions returns the destination string. No return value is reserved to indicate an error. 需要注意的是该函数在拷贝时不能遗漏 ‘\0’。根据说明实现该函数的程序如下:

#include<stdio.h>
#include<windows.h>
#include<assert.h>
char *my_strcap(char *dest,const char *str)
{
	char *ret = dest;
	assert(dest);
	assert(str);
	while(*dest++ = *str++){
		;
	}
	return ret;
}
int main()
{
	char dest[20] = {0};
	char *str = "hello word!";
	printf("%s\n",my_strcap(dest,str));
	system("pause");
	return 0;
}
strcat 函数说明:msdn 中对该函数函数原型和返回值的表达为:函数原型:char *strcat( char *strDestination, const char *strSource );返回值:Each of these functions returns the destination string (strDestination). No return value is reserved to indicate an error.该函数在连接两个字符串时要保证第一个字符串数组空间足够,当遇到第一个字符串的 ‘\0’ 时开始连接,当连接完第二个字符串的 ‘\0’ 时整个连接过程终结。根据说明该函数的实现代码如下:
 
#include<stdio.h>
#include<windows.h>
#include<assert.h>
char *my_strcat(char *dest,const char *str)
{
	char *ret = dest;
	assert(dest);
    assert(str);
	while(*dest){
		dest++;
	}
	while(*dest++ = *str++){
		;
	}
	return ret;
}
int main()
{
	char dest[30] = "hello word!";
	char *str = "hello school!";
	printf("%s",my_strcat(dest,str));
	system("pause");
	return 0;
}
strstr 函数说明:msdn 中对该函数函数原型和返回值的表达为: 函数原型:char *strstr( const char *string, const char *strCharSet );返回值:Each of these functions returns a pointer to the first occurrence of strCharSet in string, or NULL if strCharSet does not appear in string. If strCharSet points to a string of zero length, the function returns string.该函数的功能是检查某个子串在母串中是否存在的问题,当存在时,从函数返回值的描述中不难发现,此时返回的是母串中子串出现的起始地址,当不存在时,返回 NULL 。对该函数的实现思路这里简单表述一下,首先选取一个典型的母串和子串从具体问题出发寻求思路,母串为 “abcdf1234abcdef5678” 子串为 “cdef” , 这里首先将指针 lstart 和指针 newstart 均指向母串中的 a ,将指针 sstart 指向子串的 c ,保持 newstart 不动,向右移动 lstart 至到它指向 c ,此时发现 lstart  和 sstart 指向的对象一样,此时先将 newstart 也指向 c ,再将 lstart 和 sstart 同时向右移动至到 lstart 指向 f , sstart 指向 e,此时发现 sstart 还未指向 '\0' 且两个指针指向的对象不同,出现这种情况时将 sstart 恢复到原来的指向,即将它指向子串的 c ,将 newstart 指向 b (为什么不是 f ,读者先思考,后面给出答案),此时将 lstart 从 newstart 指向的位置向右移动,重复上述过程 ......,当 lstart 指向母串中的第二个 c 时,此时它的指向对象和 sstart 指向的对象一样,此时将 newstart 也指向 c 保持不变,将 lstart 和 sstart 向右移动直至 lstart 指向 5(也有可能指向 '\0'),sstart 指向 ‘\0’,此时二者指向的对象可能不一样,但此时 sstart 已指向 '\0',此时只需返回 newstart 指针即可;按以上思路走当出现 newstart 指向 '\0' 时说明母串中不存在制定的子串,此时只需返回 NULL 即可。哇,好累啊,不知道有没有说清楚。说到这里问题基本解决了,现在我们来回答上面括号中提出的问题,此时你想当 母串为 “aaab” 子串为 “aab” 时括号中的思路明显不行。好了,根据此思路该函数的实现代码如下:
#include<stdio.h>
#include<windows.h>
#include<assert.h>
const char *my_strstr(const char *longstart, const char *shortstart)
{
	const char *newstart = longstart;
	const char *lstart = NULL;
	const char *sstart = NULL;
	assert(longstart);
	assert(shortstart);
	while(*newstart){
		lstart = newstart;
		sstart = shortstart;
	while(*sstart && *lstart && *lstart == *sstart){
		lstart++;
		sstart++;
	}
	if(*sstart == '\0'){
		return newstart;
	}
	else{
		newstart++;
	}
	}
	return NULL;
}
int main()
{
	const char *longstr= "abcdf12345abcdef";
	const char *shortstr = "cdef";
	printf("%s\n",my_strstr(longstr,shortstr));
	system("pause");
	return 0;
}
strcmp 函数说明:msdn 中对该函数函数原型和返回值的表达为:

函数原型:int strcmp( const char *string1, const char *string2 );

返回值:The return value for each of these functions indicates the lexicographic relation of string1 to string2.我们这里与库中对该函数的操作保持一致,即在比较大小时优先考虑 ASCII值 再以字符串的长度作为比较字符串大小的依据或出发点。根据说明实现该函数的代码如下: #include<stdio.h> #include<windows.h> #include<assert.h> int my_strcmp(const char *dest,const char *str) { unsigned char *s1 = (unsigned char *)dest; unsigned char *s2 = (unsigned char *)str; assert(dest); assert(str); while(*s1 && *s2){ if(*s1 > *s2){ return 1; } else if(*s1 < *s2){ return -1; } else{ s1++;s2++; } } if(*s1){ return 1; } if(*s2){ return -1; } return 0; } int main() { char *dest = "abcdef1234"; char *str = "bcde"; printf("%d\n",my_strcmp(dest,str)); system("pause"); return 0; }

这里我们注意的一点是以 str 开头的函数是专门用来处理字符串的,不能处理数组。
前面的一篇博客用三种方法实现了 strlen 函数,有兴趣的朋友关注一下。
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值