字符串函数精讲1

又是好几天没有更新了,最近有些忙,但这并不是理由,还是怪我自己玩的时间多了!但还是有在每天敲代码的!话不多说,开始这一期的学习:

strlen的使用和模拟实现

• 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包含 '\0' )。

• 参数指向的字符串必须要以 '\0' 结束。

• 注意函数的返回值为size_t,是⽆符号的( 易错 )

• strlen的使用需要包含头文件 

strlen的使用:

 字符串中一共有13个字符,末尾是以\0结尾的,我们strlen函数再计算字符个数时,\0不计入其中,遇到\0才会停下来!如果末尾没有\0的话,strlen就会一直寻找它的\0,直到遇到\0才会停下来,可能会存在越界访问!所以在使用时,一定要注意!而且要加上相应的头文件哦!

strlen的模拟实现:

方法一:

既然它遇到\0就会停止,那么我们就可以创建一个变量(count)来计数,如果arr[i]不为0,那么我们就count++;

#include <stdio.h>
size_t my_strlen(char* str)
{
	int count = 0;
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	char arr[] = "i want to try";
	size_t len = my_strlen(arr);
	printf("%zu", len);
	return 0;
}

方法二:

我们可以利用指针-指针的绝对值等于之间的元素个数来模拟,我们首先保存数组的首元素地址,接着我们找到\0的位置,然后两指针相减就可以知道了。

#include <stdio.h>
size_t my_strlen(char* str)
{
	char* start = str;
	while (*str)
	{
		str++;
	}
	return str-start;
}
int main()
{
	char arr[] = "i want to try";
	size_t len = my_strlen(arr);
	printf("%zu", len);
	return 0;
}

方法三:

第三种方法我们可以利用函数递归的方法进行计算,举个例子:我们要计算的是“hello”这个字符串,那么就是hello-> 1+ello ->1+1+llo ->1+1+1+lo -> +……+1+1+1+1+1+'\0' = 5;

#include <stdio.h>

size_t my_strlen(char* str)
{
	if (*str == '\0')
	{
		return 0;
	}
	else
	{
		return 1 + my_strlen(str + 1);
	}
}

int main()
{
	char arr[] = "i want to try";
	size_t len = my_strlen(arr);
	printf("%zu", len);
	return 0;
}

strcpy 的使用和模拟实现:

源字符串必须以 '\0' 结束。

会将源字符串中的 '\0' 拷⻉到⽬标空间。

⽬标空间必须⾜够⼤,以确保能存放源字符串。

⽬标空间必须可修改。

strcpy 的使用:

 我们这时可以打开监视,看一看arr里面的情况,是只拷贝了abcd,还是把'\0'也拷贝了过去!

 可以看见是把我们的\0也拷贝过去的,所以这些小细节我们一定要拿捏好,哈哈。

strcpy 的模拟实现:

怎样实现我们strcpy的模拟实现呢?那么就是当我们源字符串不为\0时,我们就改变目的字符串的字符,直到源字符串的字符为0时,我们就跳出循环,接着把\0也copy过去!

#include <stdio.h>
#include <assert.h>

char* my_strcpy( char* str1, const char* str2)
{
	char* ret = str1;//保存str1的首地址,下面需返回首地址打印,ret在下面代码中的位置会被改变
    assert(str1 && str2);//断言是否为空指针
	while (*str2 != '\0')
	{
		*str1 = *str2;
		str1++;
		str2++;
	}
	*str1 = *str2;//把\0也拷贝过去
	return ret;
}

int main()
{
	char arr1[] = "happy new year!";
	char arr2[] = "hello baby";
	
	printf("%s", my_strcpy(arr1, arr2));
	return 0;
}

其实上述的代码中while部分的代码还可以这样写:

while((*dest++ = *src++))
 {
     ;
 }

加加的优先级高于简引用,后置加加所以是先使用再进行加加运算,当*src为\0时,赋值给*dest后,循环条件终止跳出循环!


strcat 的使用和模拟实现:

 

源字符串必须以 '\0' 结束。
⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
⽬标空间必须有足够的⼤,能容纳下源字符串的内容。
⽬标空间必须可修改。

strcat 的使用:

 就是再arr1后面追加arr2的内容,我们去看一看是否把\0也追加了过去!

那么我们可以看见也是把\0追加了过去!那么我们的这个strcat函数,可以自己给自己追加吗?

 我们可以看出,\0的位置被改成了b,那么我们的arr2就不会指向我们的\0的位置,就会成为死循环状态,那么对于自己给自己追加的话,我们后面会讲到一种函数(strncat),它就能自己给自己追加!

strcat 的模拟实现:

我们有了上面模拟strcpy的知识,那么对于这个函数,我们就只需要再前面找到arr1\0的位置,然后进行copy就可以了!

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* str1, const char* str2)
{
	char* ret = str1;
	assert(str1 && str2);
	while (*str1)
	{
		str1++;
	}//找到str1的\0的位置
	while (*str1++ = *str2++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[20] = "hello\0xxxxxxx";
	char arr2[] = "baby";
	printf("%s", my_strcat(arr1, arr2));
	return 0;
}

strcmp 的使⽤和模拟实现:

 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字

第⼀个字符串等于第⼆个字符串,则返回0

第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字
那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。

strcmp 的使用:

 strcmp 的模拟实现:

当我们arr1和arr2指向的位置的字符相等时,我们就指向下一个字符进行比较,当所指向的字符不相等时,我们就比较此时所指向的字符的ASCII值的大小来进行返回值!但是还有一种情况,当我们的arr1所指向的元素为/0时,说明此时已经比较完了,说明两字符串是相等的,那么此时我们就可以返回0!

#include <stdio.h>
#include <assert.h>

int my_strcmp(const char* str1, const char* str2)
{
    assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
	}

	return *str1 - *str2;

	/*if (*str1 > *str2)//也可以写成这种
	{
		return 1;
	}
	else
	{
		return -1;
	}*/
}
int main()
{
	char arr1[] = "abcd";
	char arr2[] = "abcd";
	int ret = my_strcmp(arr1, arr2);
	if (ret > 0)
	{
		printf("大于\n");
	}
	else if (ret == 0)
	{
		printf("等于\n");
	}
	else
	{
		printf("小于\n");
	}
	return 0;
}

strncpy 函数的使用和模拟实现:

 

拷⻉num个字符从源字符串到⽬标空间。
如果源字符串的长度小于num,则拷宝完源字符串之后,在⽬标的后边追加0,直到为num。

 

strncpy 函数的使用 :

我们可以根据打印出来的结果知道,此时并没有把arr2中的copy过去,因为如果copy过去的话,那么我们就只会看见hello!那么我们的num如果大于我们字符串的长度,会是什么结果呢?我们一起来看一看:

我们可以看见当我们的num大于我们的arr2的字符串长度时,我们的\0时拷贝过去了的,那么是拷贝了几个呢?我们一起看看咯:

是两个\0,那么我们就可以知道了:如果源字符串的长度小于num,则拷宝完源字符串之后,在⽬标的后边追加0,直到为num!

​​​​​​​strncpy 函数的模拟实现: 

我们有了上面模拟strcpy的经验,那么对于此函数我们想要模拟也不难咯!那么当我们的num小于等于我们的字符串的长度时,我们此时就以num为循环条件,当我们的num变为0时,我们就跳出循环,返回arr1的首元素地址:

if (num <= len)
{
	while (num--)
	{
		*dest = *src;
		dest++;
		src++;

	}
	return ret;
}

当大于的时候,我们除了copy完我们arr2的字符外,还要copy我们的\0,那么多出来的此数就copy我们的\0!

else
{
	while (len--)
	{
		*dest = *src;
		dest++;
		src++;
	}
	for (size_t i = a; i < num; i++)
	{
		*dest = '\0';
		dest++;
	}
	return ret;
}

我们来看看整体的代码:

char* my_strncpy(char* dest, const char* src, size_t num)
{
	char* ret = dest;
	assert(dest && src);
	size_t len = strlen(src);
	size_t a = len;//保存len的值,下面要用,因为len的值被改变了
	if (num <= len)
	{
		while (num--)
		{
			*dest = *src;
			dest++;
			src++;

		}
		return ret;
	}
	else
	{
		while (len--)
		{
			*dest = *src;
			dest++;
			src++;
		}
		for (size_t i = a; i < num; i++)
		{
			*dest = '\0';
			dest++;
		}
		return ret;
	}
}
int main()
{
	char arr1[20] = "xxxxxxxxxxxx";
	char arr2[] = "hello";
	my_strncpy(arr1, arr2, 7);
	printf("%s", arr1);
	return 0;
}

我们还可以用其他的方法,用两个for循环就可以解决问题了:

char* my_strncpy(char* dest, const char* src, size_t n) 
{
	size_t i;
	for (i = 0; i < n && src[i] != '\0'; i++)
	{
		dest[i] = src[i];
	}
	for (; i < n; i++) 
	{
		dest[i] = '\0';
	}
	return dest;
}

 i < n && src[i] != '\0'这样就很好的解决了我们的问题!


strncat 函数的使用和模拟实现:

Appends the first num characters of source to destination, plus a terminating null-character. (将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追⼀个 \0 符)。
If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.(如果source 指向的字符串的⻓度⼩于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾)。

strncat 函数的使用:

 我们的num值为3,那么·追加过去的除了wor三个字符,还有我们的\0。那么如果我们追加的Num值大于字符串长度呢?又会是什么样的结果呢?一起来看一看:

那么可以看见不管多了多少,也只是在后面追加了一个\0!

strncat 函数的模拟实现:

这里就直接展示代码嘛:有了上面的经验,相信大家都是会的吧!

#include <stdio.h>
#include <assert.h>
//方法一:
char* my_strncat(char* dest, const char* src, size_t num)
{
	char* ret = dest;
	assert(dest && src);
	int j = 0;
	while (dest[j])
	{
		j++;
	}
	size_t i = 0;
	for (i = 0; i < num && src[i] != '\0'; i++)
	{
		dest[j] = src[i];
		j++;
	}
		dest[j] = '\0';
	return ret;
}

//方法二:
//char* my_strncat(char* destination, const char* source, size_t num)
//{
//    char* ptr = destination;
//    while (*ptr) 
//    {
//        ptr++;
//    }
//
//    while (*source && num) 
//    {
//        *ptr++ = *source++;
//        num--;
//    }
//
//    *ptr = '\0';
//
//    return destination;
//}
//
//int main() 
// {
//    char str1[30] = "Hello \0xxxxxxxx";
//    char str2[] = "World!";
//
//    printf("%s\n", my_strncat(str1, str2, 9));
//
//    return 0;
//}

strncmp函数的使用:

⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不⼀ 样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0.

这里就讲一下怎么使用的,感兴趣的伙伴可以去模拟实现一下看看哦!

相信你们一定可以的!本期的内容就到此了,我们下期再见!

  • 43
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

并不会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值