与字符串相关的函数

一、求字符串长度的函数

strlen

二、长度不受限制的字符串函数

strcpy

strcmp

strcat

三、长度受限制的字符串函数

strncpy

strncat

strncmp

四、字符串查找

扫描二维码关注公众号,回复: 12614616 查看本文章

strstr

strtok

五、错误信息报告

strerror

一、求字符串长度的函数

strlen

注意:

1.strlen函数返回的是字符串中'\0'前面出现的字符个数(不包含'\0')

2.该函数的参数类型是一个char类型的指针,返回值是size_t(无符号整形)

3.因为返回值是size_t,所以不能用函数的返回值相比较或做运算

(挖个坑)  strlen的模拟实现(1.计数器的方式  2.递归的方式  3.指针减去指针的方式)

二、长度不受限制的字符串函数

1.字符串拷贝函数

strcpy

注意:1.要保证目标空间足够大

           2.目标空间必须可变,因此不能在第一个参数前加const

参数类型:1.char *strDestination

                  2.char *strSource

返回类型:char*

strcpy的模拟实现

普通版(已引头文件):

//strcpy的模拟实现
void my_strcpy(char *dest, char *src)
{
	while (*src != '\0')
	{
		*dest = *src;
		src++;
		dest++;
	}
	*dest = *src;
}
int main()
{
	char arr1[20] = "#########";
	char arr2[20] = "hello world";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

高级版:

//strcpy的模拟实现
#include<string.h>
#include<assert.h>
char* my_strcpy(char *dest,const char *src)
{
	assert(dest && src);//断言,提高指针的安全性
	char *ret = dest;
	while (*dest++ = *src++)//字符串的拷贝,先拷贝,后++,当把'\0'也拷贝过去后,括号里表达式结果为0,为假,跳出循环
	{
		;
	}
	return ret;//返回目标空间的起始地址
}
int main()
{
	char arr1[20] = "#########";
	char arr2[20] = "hello world";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

2.字符串追加函数

strcat

注意:1.要追加的目标空间必须足够大

           2.要追加的空间必须可修改

           3.目标字符串和源字符串必须要有'\0'

           4.不能自己给自己追加

参数:1.char *strDestination

           2.char *strSource

返回类型:char*

模拟实现

//strcat的模拟实现
#include<assert.h>
char* my_strcat(char *dest, const char *src)
{
	assert(dest && src);
	char *ret=dest;
	//1.找到目标字符串的'\0'
	while (*dest)
	{
		dest++;
	}
	//2.追加
	while (*dest++ = *src++);
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[20] = "hello ";
	char arr2[] = "world";
	
	printf("%s\n", my_strcat(arr1, arr2));
	return 0;
}

3.字符串比较函数

strcmp

注意:

1.比较的是对应的字符的ASCII码值,不是比较字符串长度

2.前者>后者,返回一个>0的数;前者=后者,返回0;前者<后者,返回一个<0的数

参数:1.char *str1

           2.char *str2

返回类型:int

模拟实现

//strcmp的模拟实现
#include<assert.h>
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 arr1[10] = "abc";
	char arr2[10] = "abcde";
	int ret = my_strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

三、长度受限制的字符串函数(与受限制的函数相比多了一个参数size_t  count,用来记录要操作的字符个数)

与长度不受限制的函数差不多,较简单,不做过多说明

四、字符串查找函数

1.strstr(查找子串)

能找到的情况:

//strstr查找子串函数
#include<string.h>
int main()
{
	char arr1[20] = "abcdef";
	char arr2[20] = "bcde";
	char *ret = strstr(arr1, arr2);//在arr1中查找arr2第一次出现的位置,并返回arr1中第一个被查找的字符的首地址,将该地址打印后可打印出arr1从该字符起之后的字符串
	printf("%s\n", ret);//bcdef
	return 0;
}

判断能否找到的情况:

//strstr查找子串函数
#include<string.h>
int main()
{
	char arr1[20] = "abcdef";
	char arr2[20] = "bcde";
	char *ret = strstr(arr1, arr2);//在arr1中查找arr2第一次出现的位置,并返回arr1中第一个被查找的字符的首地址,将该地址打印后可打印出arr1从该字符起之后的字符串
	if (ret != NULL)
		printf("%s\n", ret);//bcdef
	else
		printf("找不到\n");
	return 0;
}

模拟实现(难点)

//strstr模拟实现
#include<assert.h>
char* my_strstr(const char *s1,const char *s2)
{
	assert(s1 && s2);//断言
	const char *cp = s1;

	if (*s2 == '\0')
		return (char*)s1;//特殊情况

	while (*cp)//判断*cp是否等于\0
	{
		const char *p1 = cp;
		const char *p2 = s2;
		while ((*p1) && (*p2) && (*p1 == *p2))
		{
			p1++;
			p2++;
		}
		if (*p2 == '\0')
			return (char*)cp;

		cp++;
	}
	return NULL;
}
int main()
{
	char arr1[20] = "abbbcdef";
	char arr2[20] = "bbc";
	char *ret = my_strstr(arr1, arr2);
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到子串\n");
	return 0;
}

2.strtok(切割字符串)

char * strtok ( char * str , const char * sep );
 
参数:1.要切割的字符串
           2.分割标记
返回值:每次返回分割的字符串的首地址
 
大致用法如下:
//strtok
#include<string.h>
int main()
{
	char arr1[30] = "123456.3.haha@qq";
	char arr2[30] = { 0 };
	char p[30] = ".@";
	strcpy(arr2, arr1);//将arr1拷贝到arr2,使得arr1得以保留,我们操作arr2
	char *ret;//接收strtok函数的返回值,为一个指针
	//用循环的方式打印,第一次调用的时候第一个参数传参要传字符串,之后只用传空指针就可以
	for (ret = strtok(arr2,p); ret != NULL; ret = strtok(NULL, p))
	{
		printf("%s\n", ret);
	}
	return 0;
}

strtok函数的古怪之处在于它第一次调用的时候第一个参数传参要传字符串,而之后只用传空指针,这是static的功劳,它帮助strtok函数每次调用之后都能保留原来指针的位置,而它开辟的内存不会随着调用的结束而销毁。

五、错误报告函数

strerror

功能:把错误码转换为对应的错误信息,返回错误信息对应字符串的起始地址

猜你喜欢

转载自blog.csdn.net/qq_52454367/article/details/113893400