字符串函数的模拟实现(strlen,strcpy,strcat,strstr, strcmp)

1.实现strlen

sizt_t    strlen (const char *str1);//定义如此

函数返回值是一个无符号整形数据,参数类型是一个字符指针。

代码实现如下:

size_t my_strlen(char const *str1)
{
	size_t count = 0;
	while (*str1++)
	{
		count++;
	}
	return count;
}
int main()
{
	char str[] = "1234567";
	printf("%u",my_strlen(str));
	return 0;
}

2.实现strcpy

查阅msdn知道strcpy的函数声明形式如下

char *strcpy( char *strDestination, const char *strSource 

基本用法如下

将字符数组arr2(源操作数)中的字符复制到arr1(目的操作数)中。  

void my_strcpy(char* dest, char* ser)
{
     //字符串复制
	while (*dest++ = *ser++)
	{
		;
	}
}
int main()
{
	char arr1[20] = "***********";
	char arr2[] = "student";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

while (*dest++ = *ser++)   

·1:后置++的表达式,先使用变量,后对变量进行自增。

2:直接在while循环中进行赋值,因为每一个字符串在定义时,系统会默认加上一个‘\0’(字符串结束标志)而'\0'的ascll码值是0,所以当这个赋值操作进行到‘\0’时,*dest先被赋值为\0,然后while循环判断结果,因其结果为0,所以判断为假跳出循环。而前面的字符串的ascll码值都不为0,那就都判断为真,循环继续。

 当然我们也要防止函数传参时传了一个空指针。所以在复制前可以加上assert函数(断言函数)

断言函数,中间操作数是指针变量本身,不是解引用后所指向的变量。

 如果传参时传过来的参数为NULL,那么系统会报错,编译不能通过。并且会提醒错误位置

 再来比较msdn中定义的标准形式     char *strcpy( char *strDestination, const char *strSource 

在源操作数前有一个const关键字,修饰常变量,被他修饰后,变量中的数据不能通过const修饰过的变量名进行改变(但可以通过指针来改变变量中的数据)这里用来防止字符串赋值时,源操作数和目的操作数写反(会导致结果不能达到预期)

现在 唯一不同的就是函数的返回类型,msdn中strcpy函数返回类型是char *  一个指向字符类型的指针(就是源操作数的首地址)

  printf("%s\n", my_strcpy(arr1, arr2));//函数的链式访问,

一个函数的返回值,作为另一个函数的一个操作数。

所以要进行链式访问,那么该函数必须要有返回值。(函数的返回类型不能为void)

下面就是my_strcpy函数的完整实现

char* my_strcpy(char* dest, const char* ser)
{
	//字符串复制
	assert(dest != NULL);//断言
	//用法和if相同,不满足就会报错
	assert(ser != NULL);
	char* ch = dest;
	while (*dest++ = *ser++)
	{
		;
	}
	return ch;
}
int main()
{
	char arr1[20] = "***********";
	char arr2[] = "student";
	printf("%s\n", my_strcpy(arr1, arr2));//函数的链式访问
	return 0;
}

3:stscat

char *strcat( char *strDestination, const char *strSource )

通过调试的方法可知strcat的功能,然后编写程序进行实现。

功能:字符串追加函数,在目的操作数最后追加上源操作数

//实现strcat
#include<stdio.h>
#include<assert.h>
//char *strcat( char *strDestination, const char *strSource )
char* my_strcat(char* dest,char* str )
{
	assert(dest);//断言函数
	assert(str);//传参时二者都不能为空指针
	char* ch = dest;
	while (*dest++ != '\0')
	{//数到指针指向第一个为\0的字符
		;
	}//此时*dest指向第一个‘\0’的后一个位置。
	dest--;
	while (*dest++ = *str++)
	{
		;
	}
	return ch;
}
int main()
{
	char arr1[20] = "hello ";
	char arr2[] = "world";
	printf("%s", my_strcat(arr1, arr2));
	return 0;
}

4:strstr

char *strstr( const char *string, const char *strCharSet )

功能如下:

查询源操作数的字符串在目的操作数的位置,查询成功返回源操作数所在位置的地址,查询不到则返回NULL.

#include<stdio.h>
#include<string.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	int count = 0;
	char* s2 = str2;
	while (1)//
	{
		while (*str1 != *str2 && str1 != 0)
		{//加第二个条件防止str1越界
			str1++;
		}		
		char* s1 = str1;//记录第一个相同字符的位置。
		while ( (*str1 == *str2)&&*str1 && *str2  )
		{//计数,记录从第一个相同字符开始
		 //后面相同字符的个数
	     //在进行比较时,++或者--不要放在while条件中
		 //在赋值时可以。
			str1++;
			str2++;		
		}	
		if (*str2 == 0)
		{//如果记录的字符相同的个数和str2中
		 //字符个数相同,返回此时str1中第一个相同字符的地址
			return s1;
		}
		else
		{//否则就让str2回到第一个字符的位置重新开始比较
		 //并且让str1回到刚才第一个相同字符的后面一个位置。
			str2 = s2;
			str1 = s1 + 1;
		}	
		count = 0;	
		if (*str1 == 0)
		{
			return NULL;
		}	
		
	}
}
int main()
{
	char arr1[] = "abbbbbcjias";
	char arr2[] = "bbbc";
	char *s = my_strstr(arr1, arr2);
	if (s == NULL)
	{
		printf("没找到 \n");
	}
	else
	{
		printf("找到了  %s\n",s);
	}
	return 0;
}

5:strcmp

定义如下: int strcmp( const char *string1, const char *string2 );

功能,比较两串字符串,相同返回0,*string>*string2返回1   *string<*string2返回-1.

要特别注意:在对两字符串进行比较时,是两字符串的每一个对应位的字进字符行比较,于字符串本身的长度无关。

#include<stdio.h>
#include<assert.h>
#include<string.h>
int my_strcmp(const char* string1, const char* string2)
{
	//断言函数
	assert(string1);
	assert(string2);
	while (*string1)
	{
		if ((*string1 == *string2 ) && *string1 != 0  && *string2 != 0)
		{
			string1++;
			string2++;
		}
		if (*string1 > *string2)
		{
			return 1;
		}
		if (*string1 < *string2)
		{
			return -1;
		}
	}
	return 0;
}
int main()
{
	while (1)
	{
		char ch[20] = { 0 };
		char ch1[20] = { 0 };
		gets(ch);
		gets(ch1);
		//int a = strcmp(ch, ch1);
		printf("%d\n", my_strcmp(ch, ch1));
		printf("%d\n", strcmp(ch, ch1));
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值