全网超详细C语言字符串函数的使用、剖析、以及模拟实现

目录

(一)、strlen:求字符串长度

1.函数的作用:

2.函数声明:

3.函数注意事项:

4.函数使用实例:

5.strlen函数的模拟实现:(三种方法)

(1).计数器法

(2).指针 - 指针

(3)递归方法

(二)、strcpy:字符串拷贝

1.函数声明:

2.函数的作用:

3.函数注意事项:

4.函数使用实例:

5.strcpy函数的模拟实现:

源代码:

解释:

(三)、strcat:字符串追加

1.函数声明:

2.函数的作用:

3:函数注意事项:

4:函数使用实例:

5:strcat函数的模拟实现:

源代码:

解释:

(四)、strcmp:字符串比较

1.函数声明:

2.函数的作用:

3.函数使用实例:

4.strcmp函数的模拟实现:

源代码:

解释:

(五)、strstr:字符串中找子串

1.函数声明:

2.函数的作用:

3.使用实例:

4.strstr函数的模拟实现:

(六)、strtok:字符串切割


(一)、strlen:求字符串长度

1.函数的作用:

用于求取一段字符串的长度。

2.函数声明:

size_t strlen ( const char * str );

解释:

(1).函数形参为一个char*指针str,用于接收待求字符串的首地址,const的作用是防止指针str发生改变。

(2).函数返回值为str所指向的字符串的长度,遇见'\0'结束统计,返回值类型为size_t(无符号整型)。

3.函数注意事项:

(1).我们知道,字符串以‘\0’作为结束标志,strlen函数返回的就是字符串中'\0'之前的出现的字符个数。

(2).参数str指向的字符串必须以'\0'结束,否则会出现难以预料的结果。

(3).该函数包含在头文件<string.h>中。

4.函数使用实例:

如下图:

 前面三个都还好理解,数组大小为6字节,但前三种初始化,末尾会自动添加‘\0’,所以需要一字节空间存储'\0',所以字符串长度为5。而第四种初始化方式,字符串末尾不会自动添加'\0',所以strlen会一直统计下去,知道遇到'\0',才停止,所以会算出随机值的情况

5.strlen函数的模拟实现:(三种方法)

(1).计数器法

源代码如下:

//计数器模拟实现strlen
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
	assert(str);
	size_t count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

int main()
{
	size_t sz = my_strlen("abcdef");
	printf("该字符串长度为:%zu\n", sz);
	return 0;
}

解释:

①:既然是模拟实现,所以参数与返回值类型都应该相同。

②:根据strlen函数统计原理,遇见'\0'停止,所以我们只需要创建一个变量(计数器),用一个while循环,当指针str所指向的值不等于'\0'时,计数器就+1,然后指针+1判断下一个字符,直到str所指向的值等于'\0',循环结束。最后返回计数器的值即可。

③:有的小伙伴可能不认识assert这个函数,其实这个函数只是用来检验指针str是否为空,感兴趣的小伙伴可以自行了解,不敢兴趣的伙伴可以不管。

(2).指针 - 指针

源代码如下:

//指针-指针实现strlen
#include<assert.h>
#include<stdio.h>
size_t my_strlen(const char* str)
{
	assert(str);
	const char* end = str;
	while (*end != '\0')
	{
		end++;
	}
	return end - str;
}

int main()
{
	size_t sz = my_strlen("abcdef");
	printf("该字符串长度为:%zu\n", sz);
	return 0;
}

解释:

①:首先我们需要明白一点,指针 - 指针得到的是什么呐?

答:指针 - 指针得到的是两指针之间的元素个数

②:所以根据上述,我们可以在创建一个与str同类型的指针end,并将str赋值给end,然后通过while循环,将end所指向的值指向该字符串中的'\0',如上,通过++操作即可达到目的。

③:最后返回end - str即可,即'\0'与首地址处之间的元素个数,示意图如下:

(3)递归方法

源代码如下:

//递归实现strlen
size_t my_strlen(const char* str)
{
	if (*str != '\0')
	{
		str++;
		return 1 + my_strlen(str);
	}
	return 0;
}

int main()
{
	size_t sz = my_strlen("abcdef");
	printf("该字符串长度为:%zu\n", sz);
	return 0;
}

解释:

因为递归太抽象,所以我们画图理解,如下图:

(二)、strcpy:字符串拷贝

1.函数声明:

char * strcpy ( char * destination, const char * source );

解释:

①:函数有两个形参

第一个形参为char*指针,即为目标空间;

第二个形参const char*指针,即为源字符串。

我们就是要把source指针指向的源字符串拷贝到目标空间里面去。

②:返回值为目标空间的首地址(方便用于函数的链式访问)。

③:该函数包含在头文件<string.h>中。

2.函数的作用:

参考函数声明,就是将形参source指向的源字符串拷贝到形参destination所指向的目标空间里面去,包含'\0'。

3.函数注意事项:

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

②:会把源字符串的'\0'也拷贝到目标空间里面去。

③:目标空间必须足够大,以确保能够存放源字符串。

④:目标空间必须可变,所以没有用const修饰。

4.函数使用实例:

1.正常使用:

源代码如下:

#include<string.h>
#include<stdio.h>
int main()
{
	char arr1[] = { 'a','b','c','\0' };
	char arr[10] = " ";
	strcpy(arr, arr1);
	printf("%s\n", arr);
	return 0;
}

运行结果:

 2.若目标空间不够大的情况:

3.目标空间不可变的情况:

5.strcpy函数的模拟实现:

源代码:
//模拟实现strcpy
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* sour)
{
	assert(dest && sour);
	char* tmp = dest;
	while (*dest++ = *sour++)
	{
		;
	}
	return tmp;
}

int main()
{
	char arr[] = "abcdef";
	char dest[10] =" ";
	my_strcpy(dest,arr);
	printf("%s\n", dest);
	return 0;
}
解释:

①:既然是模拟实现,所以返回类型,参数都应该相同。

②:思路:是一个字符一个字符的拷贝,直到遇见'\0'结束。

③:因为我们需要返回目标空间的起始地址,所以开头先创建一个指针变量tmp保存目标空间的起始地址。

④:接着我们用一个while循环用于一个字符一个字符的拷贝,将sour指向的值赋给dest指向的空间,接着判断sour指向的值是否等于'\0',若不等于,则sour和dest都+1,拷贝下一个字符;若等于'\0',将'\0'拷贝后循环结束,所以'\0'的ASCII值等于0。

⑤:最后返回目标空间首地址tmp。

(三)、strcat:字符串追加

1.函数声明:

char * strcat ( char * destination, const char * source );

解释:

①:函数有两个形参
第一个形参为char*指针,即待追加字符串(目标空间),所以不用const修饰。

第二个形参为const char*指针,即源字符串,源字符串不能改变,所以用const修饰。

该函数就是把source指向的源字符串追加到destination指向的待追加字符串的末尾。

②:函数返回值为待追加字符串的首地址。

③:该函数包含在头文件<string.h>中。

2.函数的作用:

参考函数声明,即把source指向的源字符串追加到destination指向的待追加字符串的尾部。

3:函数注意事项:

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

2.目标空间必须足够大,能够容纳下源字符串。

3.目标空间必须可修改。

4.尽量别自己给自己追加。

4:函数使用实例:

源代码如下:

#include<string.h>
int main()
{
	char arr[] = "world";
	char dest[20] = "hello ";
	strcat(dest, arr);
	printf("%s\n", dest);
	return 0;
}

运行结果:

5:strcat函数的模拟实现:

源代码:
//模拟实现strcat
#include<assert.h>
#include<stdio.h>
char* my_strcat(char* destination, const char* source)
{
	assert(destination && source);
	//存目标空间首地址
	char* tmp = destination;
	//找到目标空间'\0'的位置;
	while (*destination)
	{
		destination++;
	}
	//从目标空间'\0'位置开始,将源字符串的字符一个个的拷贝进来,与strcpy类似
	while (*destination++ = *source++)
	{
		;
	}
	return tmp;

}

int main()
{
	char arr[] = "world";
	char dest[20] = "hello ";
	my_strcat(dest, arr);
	printf("%s\n", dest);
	return 0;
}
解释:

①:因为是模拟实现,所以返回值,参数都应该相同。

②:思路:先找到目标空间的'\0'位置处,然后从此位置开始,将源字符串的内容一个字符一个字符的拷贝过来,直到拷贝到源字符串的'\0'结束。

③:因为返回值是目标空间的首地址,所以开始先将首地址保存在变量tmp中。

④:然后用一个while循环,将指针destination指向目标空间的'\0'位置处。

⑤:从此位置开始,用strcpy函数模拟实现的方法,将源字符串的内容一个一个字符拷贝过来,直到拷贝到源字符串的'\0'后循环结束。

⑥:最后返回目标空间首地址tmp。

⑦:该模拟实现有一个缺点,就是不能自己给自己追加。

(四)、strcmp:字符串比较

1.函数声明:

int strcmp ( const char * str1, const char * str2 );

解释:

1.该函数有两个参数,参数类型一样,因为只需要进行比较,不能改变原字符串内容,所以用const修饰。

2.该函数返回类型为int,返回值根据下述标准适用。

3.该函数包含在头文件<string.h>中。

2.函数的作用:

该函数是用于两段字符串的比较,

比较方法

将两字符串对应位置处的字符拿出来一个一个的比较ASCII码值,若第一个字符相同,即ASCII码值相同,则比较第二个字符的ASCII码值。

比较规则

3.函数使用实例:

4.strcmp函数的模拟实现:

源代码:
//模拟实现strcmp
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0' && *str2 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

int main()
{
	printf("%d\n", my_strcmp("abc", "azc"));
	return 0;
}
解释:

①:因为是模拟实现,因为返回值,参数都应该相同。

②:首先一个while循环判断两字符串是否相等,一个字符一个字符的判断,若都相等,则判断到'\0'处就返回0;若比较到某个字符不相等,则出循环,然后返回*str1 - *str2,因为我们是根据ASCII码值来比较的,所以如果*str1大于*str2,则两者相减返回的是一个大于0的数,如果*str1小于*str2,则两者相减返回的是一个小于0的数,这与标准刚好吻合。

(五)、strstr:字符串中找子串

1.函数声明:

const char * strstr ( const char * str1, const char * str2 );
      char * strstr (       char * str1, const char * str2 );

解释:

1.该函数有两个参数,就是在主串str1中查找看是否存在子串str2。

2.返回值:

若主串str1中找不到子串str2,则返回NULL(空指针)。

若找到了,则返回子串str2在主串str1中第一次出现的首地址。

2.函数的作用:

即在主串str1中找子串str2:

找不到,返回NULL。

找到了,返回子串str2在主串str1中首次出现的首地址。

3.使用实例:

 

4.strstr函数的模拟实现:


//模拟实现strstr
#include<assert.h>
char* my_strstr(char* str1, char* str2)
{
	assert(str1 && str2);
	char* cp = str1;
	char* s1 = cp;
	char* s2 = str2;
	while (*cp)
	{
		//开始匹配
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return cp;
		}
		cp++;
	}
	return NULL;
}

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

(六)、strtok:字符串切割

因为该函数很少使用,所以只做以下说明;

函数使用实例:

本次知识到此结束,希望对你有所帮助!

猜你喜欢

转载自blog.csdn.net/hffh123/article/details/132347710