strlen strcpy-strncpy strcat-strncat strcmp-strncmp- - ->字符函数和字符串1

6-4,6-6
今日推荐
搜索文件工具:everything

在这里插入图片描述

字符函数和字符串

1、strlen

实现strlen函数的三种方法:

  1. 计数器的版本
  2. 递归的版本
  3. 指针-指针

计数器的版本

#include <stdio.h>
#include <string.h>
#include <assert.h>
int my_strlen(const char* str)
//因为传的是数组名的首地址,所以形参用指针来指向,因为在这个函数里面没有改变这个数组,所以加常量字符串const更加安全
{
	int count = 0;//计数器
	assert(str != NULL);

	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	 char arr[] = "abc";
	//char arr[] = { 'a', 'b', 'c' };//随机值

	int len  = my_strlen(arr);

	printf("%d\n", len);
	return 0;
}
  • 用count来记录长度

指针-指针方法
写法1:

//int my_strlen(char* str)
//{
//	char* start = str;
//	while (*str != '\0')
//	{
//		str++;
//	}
//	return str - start;
//}
//
//int main()
//{
//	//strlen(); - 求字符串长度
//	//递归
//	int len = my_strlen("abc");
//	printf("%d\n", len);
//
//	return 0;
//}
  • 刚开始传的是字符串的首地址到strlen函数里面
  • 再用指针指向这个起始地址,,再使指针一步步的指向找到字符串的最后一个元素
  • 最后两个指针变量相减,就可以求出长度

写法2:
输出>

int main()
{
	if (strlen("abc") - strlen("abcdef") > 0)
	{
		printf(">\n");
	}
	else
	{
		printf("<=\n");
	}
	return 0;
}

在这里插入图片描述

  • size-t为无符号类型
  • my_strlen(“abc”) - my_strlen(“abcdef”)为无符号整数-无符号整数=无符号数,算出-3,但是当作无符号数,它的补码被解析为结果,就会是一个很大的数,输出>
    写法3:
    输出<=
#include <stdio.h>
#include <string.h>
#include <assert.h>
int my_strlen(const char* str)
{
	int count = 0;//计数器
	assert(str != NULL);

	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	if (my_strlen("abc") - my_strlen("abcdef") > 0)
	{
		printf(">\n");
	}
	else
	{
		printf("<=\n");
	}
	return 0;
}
  • 用自己的的my-strlen 解析为有符号数了所以输出<=

递归方法

#include <string.h>
int my_strlen(char* str)
{
	if (*str != '\0')
		return 1 + my_strlen(str + 1);
	else
		return 0;
}
int main()
{
	char arr[] = "bit";
	//['b']['i']['t']['\0']
	//
	//模拟实现一个strlen函数
	printf("%d\n", my_strlen(arr));

	return 0;
}

2、strcpy

在这里插入图片描述
知识点:

  • 字符串:把\0也拷贝过去了
  • 字符:没有\0会出错
    会将源字符串的\0拷贝到目标空间
int main()
{
	char arr[20] = {0};
	strcpy(arr, "hello");//string copy
	printf("%s\n", arr);
	return 0;
}

在这里插入图片描述
** 源字符串必须以\0结束**

int main()
{
	char arr[20] = "#########";
	char arr2[] = { 'a', 'b', 'c' };
	strcpy(arr1[], arr2[]);
	printf("%s\n", arr);
	return 0;
}
  • 这里没有\0拷过去,会出错

目标空间必须可修改

int main()
{
	char* str = "xxxxxxxxxxxxxxxxxxx";
	char* p = "hello world";
	strcpy(str, p);
	printf("%s\n", arr);
	return 0;
}
  • 目标空间为常量字符串( char* str = “xxxxxxxxxxxxxxxxxxx”;),指针指向一个常量字符串所以不能修改,会出错

目标空间要足够大,以确保能存放源字符串

int main()
{
	char arr[5] = "####";
	char* p = "hello world";
    strcpy(arr, p);
	printf("%s\n", arr);
	return 0;
}
  • 越界拷贝,目标字符串才5个空间,指针指向的字符串11个字符,拷过去会出错,所以目标空间要足够大
  • 虽然会出错但是会强制复制,因为数组作为目标空间的时候是可修改的

3、strcat,连接字符串

把第一个字符的\0覆盖掉,追加在后面,且追加的字符串要有\0并且会追加到过去
模拟实现:
1、找到目标字符串中的\0
2、源数据追加过去,包含\0
3、保证目标空间有足够的空间能让源字符串追加过去

int main()
{
	char arr[20] = "abcd";
	strcat(arr, arr);//?
	printf("%s\n", arr);
	return 0;
}

函数模拟实现

char* my_strcat(char* dest, const char*src)
{
	char* ret = dest;
	assert(dest && src);
	1. 找目标字符串中的\0
	while (*dest)
	{
		dest++;
	}
	2. 追加源字符串,包含\0
	while(*dest++ = *src++)
	{
		;
	}
	return ret;//返回的目标空间的起始地址
}
int main()
{
	char arr1[20] = "hello ";//world
	char arr2[] = "world";
	my_strcat(arr1, arr2);//字符串追加(连接)
	printf("%s\n", my_strcat(arr1, arr2));
	return 0;
}

自己追加自己:
不能,\0被改变了,找不到结束的标志\0了

4、strcmp- -比较字符串

两种不用strcmp的错误写法

	char* p = "obc";
	char* q = "abcdef";
	if (p > q)
	{
		printf(">\n");
	}
	else
	{
		printf("<=\n");
	}

在这里插入图片描述

  • 不用字符串函数strcmp比较在这里就会比较的是p和q的地址而不是比较字符串
char* p = "obc";
	char* q = "abcdef";
	if ("obc" > "abcdef")
	{
	}
  • 比较的是首字符的地址而不是整个字符串的大小

正确的写法

int main()
{

	strcmp - 字符串比较大小的
	int ret = strcmp("abbb", "abq");//<0
	int ret = strcmp("aaa", "aaa");//=0
	printf("%d\n", ret);
	return 0;
}

实现函数的时候写返回情况
要根据它的三种返回值的情况来写,因为不同编译器可能返回值不一样,但是看到肯定是这三种情况在这里插入图片描述
实现strcmp函数

//写法1
int my_strcmp(const char* s1, const char* s2)
{
	assert(s1 && s2);
	while (*s1 == *s2)
	{
		if (*s1 == '\0')//两个相等,且一个等于\0(走到末尾),另一个也\0
		{
			return 0;//两个相等为0
		}
		s1++;
		s2++;
	}
	if (*s1 > *s2)//比较ascall值
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

//写法2
int my_strcmp(const char* s1, const char* s2)
{
	assert(s1 && s2);//后面要进行解引用操作
	while (*s1 == *s2)
	{
		if (*s1 == '\0')
		{
			return 0;
		}
		s1++;
		s2++;
	}
	return *s1 - *s2;//返回值有三种情况
}
int main()
{
	char* p = "abcdef";
	char* q = "abcdef";
	int ret = my_strcmp(p, q);
	if (ret > 0)
	{
		printf("p > q\n");
	}
	else if (ret < 0)
	{
		printf("p < q\n");
	}
	else
	{
		printf("p == q\n");
	}
	return 0;
}

strncpy

在这里插入图片描述
在这里插入图片描述

  • 复制的字符串的个数小于原有字符串的个数- -正确
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "qwer";
	strncpy(arr1, arr2, 2);
	
	printf("%s\n", arr1);//qwcdef
	return 0;
}
  • 把arr2的前两个字符来覆盖arr1的前两个字符

  • 输出qwcdef

  • 复制的字符串个数大于字符串原有的个数的时候- -会出错

int main()
{
	char arr1[20] = "abcdefghi";
	char arr2[] = "qwer";
	strncpy(arr1, arr2, 6);
	
	printf("%s\n", arr1);//
	return 0;
}
  • 虽然会出错但是它实际还是传了6个字符串过去,不够的那两个传的是\0

在这里插入图片描述

strncat

在这里插入图片描述在这里插入图片描述
当链接过去的的字符串的个数小于自身有的字符串

int  main()
{
	char arr1[20] = "hello ";       
	char arr2[] = "world";
	strncat(arr1, arr2, 3);
	printf("%s\n", arr1);
	return 0;
}
  • 实现的过程其实是 hello wor\0再把war链接以后就增加\0让它结束
  • 输出hello war
    当链接过去的的字符串的个数大于自身有的字符串
int  main()
{
	char arr1[20] = "hello ";
	char arr2[] = "world";
	strncat(arr1, arr2, 10);
	printf("%s\n", arr1);

	return 0;
}
  • 实现过程(看源函数就可以知道)就是world链接过去以后变为hello world以后加\0让它停止
  • 输出hello world

strncmp

在这里插入图片描述
在这里插入图片描述

int main()
{
	char* p = "abcdef";
	char* q = "abcqwert";
	int ret = strncmp(p, q, 4);
	printf("%d\n", ret);
	return 0;
}

  • 比较两个字符串的前四个字符
  • 输出一个小于0的数(不同编译器不一样)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值