真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!

目录​​​​​​​

1. 字符分类函数

1.1 小练习

1.1.1 方法一

2. 字符转换函数

2.1 小练习的方法二

3. strlen的使⽤和模拟实现

3.1 注意事项

3.1.1 注意事项2的练习

3.2 strlen函数的模拟实现

3.2.1 方法一

3.2.2 方法二(指针—指针)

3.2.3 方法三(递归方式)

3.2.3.1 注意事项

4. strcpy的使⽤和模拟实现

4.1 注意事项

4.2 使用举例

4.2.1 注意点!!!

4.3 stcpy函数的模拟实现

4.3.1 版本一(先拷贝\0之前的字符,再拷贝\0之后的字符)

4.3.2 版本二(拷贝\0前的字符包括\0)

4.3.3 版本三 (assert,防止死循环)

4.3.4 版本四 (dest指向的空间是需要改变的,但是src指向的空间是不被期望改变的)

4.3.5 版本五 (返回目标空间的起始地址)

5. strcat的使⽤和模拟实现

5.1 注意事项

5.2 使用举例

5.3 strcat函数的模拟实现

5.4 自己追加拼接自己可以吗?

6. strcmp的使⽤和模拟实现

6.1 使用举例

6.2 strcmp的模拟实现

7. strncpy函数的使⽤和模拟实现

7.1 使用举例

7.2 strncpy函数的模拟实现

8. strncat函数的使⽤和模拟实现

8.1 使用举例

8.2 strncat函数的模拟实现

9. strncmp函数的使⽤和模拟实现

9.1 使用举例

9.2 strncmp函数的模拟实现

10. strstr的使⽤和模拟实现

10.1 使用举例

10.2 strstr函数的模拟实现

10.2.1 模拟实现思路

10.2.2 模拟实现思路优化

10.2.3 代码实现

11. strtok函数的使⽤

11.1 用途介绍

11.2 使用举例

​编辑

11.2.1 方法优化

12. strerror函数的使⽤

12.1 使用举例

12.2 相关函数perror的使用


1. 字符分类函数

C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。

这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h

这可以让我们更加方便的判断⼀个字符是属于什么类型的字符的

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第1张图片

接下来,我们以islower举例,其他函数使用的规则一样

int islower ( int c );

islower是用来返回参数是否是小写字母的,如果是小写字母就返回非零的值,如果不是小写字母就返回零

#include
#include
int main()
{
	int ret = islower('Q');
	printf("%d\n", ret);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第2张图片

1.1 小练习

接下来,让我们写一个代码,将字符串中的小写字母转大写,其他字符不变

1.1.1 方法一

思路:大小写字母相差32

#include
#include
#include
int main()
{
	char arr[] = "i AM A Student.";
	int i = 0;
	int len = strlen(arr);
	for (i = 0; i < len; i++)
	{
		if (islower(arr[i]))
		{
			arr[i] -= 32;
		}
	}
	printf("%s", arr);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第3张图片

但是,这种方法有点麻烦,让我们介绍完字符转换函数再来实现方法二

2. 字符转换函数

int tolower(int c);//将参数传进去的小写字母转大写

int toupper(int c);//将参数传进去的大写字母转小写

由此,我们可以得到方法二

2.1 小练习的方法二

#include
#include
#include
int main()
{
	char arr[] = "i AM A Student.";
	int i = 0;
	int len = strlen(arr);
	for (i = 0; i < len; i++)
	{
		if (islower(arr[i]))
		{
			arr[i]=toupper(arr[i]);
		}
	}
	printf("%s", arr);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第4张图片

3. strlen的使⽤和模拟实现

size_t strlen ( const char * str );

3.1 注意事项

注意事项:
1.strlen函数要正确获得字符串长度的话,字符串中必须要有\0
2.要注意strlen的返回值是size_t(字符串长度没有负数- - ->无符号整型)

3.1.1 注意事项2的练习

观察以下代码,判断输出符号:

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

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第5张图片

可是,结果不是-3吗?为什么结果却是>呢?

返回类型觉得结果———>-3———>3
2个无符号类型相减得到的也是无符号整型

3.2 strlen函数的模拟实现

仿照strlen函数的参数,返回值,功能,写一个类似的函数

3.2.1 方法一

#include
#include
#include
size_t my_strlen(char* str)
{
	int count = 0;//计数
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	char arr[] = "abcdef";
	size_t ret = my_strlen(arr);
	printf("%zd\n", ret);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第6张图片


3.2.2 方法二(指针—指针)

#include
#include
#include
#include
size_t my_strlen(const char* str)
{
	const char* p = str;
	assert(str != NULL);
	while (*str != '\0')
		str++;
	return str - p;
}
int main()
{
	char arr[] = "abcdef";
	size_t ret = my_strlen(arr);
	printf("%zd\n", ret);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第7张图片


3.2.3 方法三(递归方式)

#include
#include
#include
#include
size_t my_strlen(const char* str)
{
	if (*str == 0)
		return 0;
	else
		return 1 + my_strlen(str + 1);
}
int main()
{
	char arr[] = "abcdef";
	size_t ret = my_strlen(arr);
	printf("%zd\n", ret);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第8张图片

3.2.3.1 注意事项

可能会有人问str++可不可以?不行!!!

str++为什么不行?
后置++:先使用再++,str传址过去再++  ——>永远都传str的地址,str++或者++str导致str改变
str+1:str不变
但是,++str可以运行成功,但是str会改变,有隐患

4. strcpy的使⽤和模拟实现

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

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第9张图片

4.1 注意事项

注意事项:
1.原字符串必须包含\0;同时\0也会被拷贝到目标空间
2.要保证目标空间要足够大,能放得下拷贝来的数据
3.还要保证目标空间可修改

4.2 使用举例

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
int main()
{
	char s1[] = "hello world";
	char s2[20] = "xxxxxxxxxxxxx";
	strcpy(s2, s1);
	printf("%s\n", s2);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第10张图片

按理来说,应该输出:hello worldxx

调试可以看到:拷贝的时候会将原字符串中的\0也拷进去,\0也拷贝过来后拷贝就结束了

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第11张图片

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第12张图片

4.2.1 注意点!!!

常量字符串---不可以修改

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第13张图片

4.3 stcpy函数的模拟实现

4.3.1 版本一(先拷贝\0之前的字符,再拷贝\0之后的字符)

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
void my_strcpy(char* dest, char* src)
{
	while (*src != 0)
	{
		*dest = *src;
		dest++;
		src++;
	}
	//拷贝\0
	*dest = *src;
}
int main()
{
	char s1[] = "hello world";
	char s2[20] = { 0 };
	my_strcpy(s2, s1);
	printf("%s\n", s2);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第14张图片


4.3.2 版本二(拷贝\0前的字符包括\0)

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
char*  my_strcpy(char* dest,  char* src)
{
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char s1[] = "hello world";
	char s2[20] = { 0 };
	printf("%s\n", my_strcpy(s2, s1));
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第15张图片


4.3.3 版本三 (assert,防止死循环)

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
char*  my_strcpy(char* dest,  char* src)
{
	assert(dest);
	assert(src);
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char s1[] = "hello world";
	char s2[20] = { 0 };
	printf("%s\n", my_strcpy(s2, s1));
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第16张图片


4.3.4 版本四 (dest指向的空间是需要改变的,但是src指向的空间是不被期望改变的)

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
char*  my_strcpy(char* dest, const char* src)
{
	assert(dest);
	assert(src);
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char s1[] = "hello world";
	char s2[20] = { 0 };
	printf("%s\n", my_strcpy(s2, s1));
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第17张图片


4.3.5 版本五 (返回目标空间的起始地址)

strcpy的功能是将原字符串的内容拷贝到目标空间,希望目标空间的内容发生改变
所以返回目标空间的起始地址,方便观察目标空间的内容

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
char*  my_strcpy(char* dest, const char* src)
{
	assert(dest);
	assert(src);
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char s1[] = "hello world";
	char s2[20] = { 0 };
	printf("%s\n", my_strcpy(s2, s1));
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第18张图片

5. strcat的使⽤和模拟实现

char *my_strcat(char *dest, const char*src)

5.1 注意事项

注意事项:
1.从末尾追加拼接,末尾是\0,拼接结束末尾也是\0——>源头字符串要有\0(从哪里开始);目标空间中要有\0(到哪里结束)
2.目标空间要足够大,目标要可修改

5.2 使用举例

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
int main()
{
	char s[20] = "hello ";
	const char* p = "world";
	strcat(s, p);
	printf("%s\n", s);
	return 0;
}

5.3 strcat函数的模拟实现

模拟实现步骤:
1.找到目标空间\0
2.拷贝数据——strcpy函数

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第19张图片

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
char* my_strcat(char* dest,const char* src)
{
	char* ret = dest;
	while (*dest != '\0')
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char s[20] = "hello ";
	const char* p = "world";
	printf("%s\n", my_strcat(s, p));
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第20张图片

5.4 自己追加拼接自己可以吗?

不可以❌

不行❌会自己把\0不断覆盖掉——>越界访问

6. strcmp的使⽤和模拟实现

比较2个字符串的大小

比较两个字符串中对应位置上的字符按照字典顺序比较

• 标准规定:

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

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

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

◦ 那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。

6.1 使用举例

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第21张图片

#include
#include
#include
#include
int main()
{
	char s1[] = "abcdef";
	char s2[] = "abcq";
	int ret=strcmp(s1, s2);
	printf("%d\n", ret);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第22张图片

6.2 strcmp的模拟实现

#include
#include
#include
int my_strcmp(const char* str1, const char* str2)//只是比较大小,不用修改值
{
	assert(str1 != NULL);//确保指针有效性
	assert(str2 != NULL);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')//只需要比较其中一个是否是\0,成立则都是\0
			return 0;
		str1++;
		str2++;
		if (*str1 > *str2)
			return 1;
		else
			return 1;
	}
}
int main()
{
	int ret = my_strcmp("abcdef", "abcdg");
	printf("%d\n", ret);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第23张图片

7. strncpy函数的使⽤和模拟实现

char * strncpy ( char * destination, const char * source, size_t num ); 

• 拷⻉num个字符从源字符串到⽬标空间。

• 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个

7.1 使用举例

#include
#include
int main()
{
	char arr1[10] = "xxxxxxxxxx";
	char arr2[] = "ab";
	strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);

	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第24张图片

我们可以通过调试看见,多余的位置用\0来凑​​​​​​​

7.2 strncpy函数的模拟实现

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第25张图片

8. strncat函数的使⽤和模拟实现

8.1 使用举例

提供参数大于传输全部个数,则全部传输,并且无论长短传输\0不变

#include
#include
int main()
{
	char s1[20] = "abc\0xxxxxxxx";
	char s2[] = "def";
	strncat(s1, s2,5);
	printf("%s\n", s1);
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第26张图片

8.2 strncat函数的模拟实现

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第27张图片

9. strncmp函数的使⽤和模拟实现

int strncmp ( const char * str1, const char * str2, size_t num );

9.1 使用举例

#include
#include
int main()
{
	char s1[15] = "abcdef";
	char s2[] = "abcg";
	int ret = strncmp(s1, s2, 3);
	printf("%d\n", ret);
	return 0;
}

​​​​​​​

9.2 strncmp函数的模拟实现

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第28张图片

10. strstr的使⽤和模拟实现

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

strstr函数的功能:

在字符串中找一个字符串

返回str2在str1中第一次出现的位置;如果str2在str1中没有出现,就返回NULL

10.1 使用举例

#include
#include
#include
int main()
{
	char s1[] = "abcdefabcdef";
	char s2[] = "efabc";
	char* ret = strstr(s1, s2);
	if (ret != 0)
		printf("找到了,是%s\n", ret);
	else
		printf("找不到\n");

	return 0;
}

10.2 strstr函数的模拟实现

10.2.1 模拟实现思路

首先,我们会想到遍历,当我们成功找到字符串时,却发现没有记住匹配成功的首个字符位置,无法返回首元素的地址,而且这只是最简单一种情况,我们直接就找到了

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第29张图片

10.2.2 模拟实现思路优化

我们要考虑到多次查找和首元素的地址确定

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第30张图片

10.2.3 代码实现

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第31张图片

11. strtok函数的使⽤

char * strtok ( char * str, const char * sep);

11.1 用途介绍

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第32张图片


解析:

• sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合

• 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标记//第一个参数指向的字符串是由sep指向的第二个参数指向的字符串分割的

• strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷⻉的内容并且可修改。)//将分割符变成\0,并返回标记的起始地址,打印的时候到\0停止

• strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置//记住\0的位置

• strtok函数的第⼀个参数 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记

• 如果字符串中不存在更多的标记,则返回 NULL 指针

11.2 使用举例

#define  _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
int main()
{
	char s[] = "[email protected]";//字符串
	char* p = "@.";//分隔符
	char *ret = strtok(s, p);
	printf("%s\n", ret);
	return 0;
}

11.2.1 方法优化

如果分割符过多的话,则上面的方法过于冗长,需要我们一次次的运行,那我们可以将字符串拷贝到目标空间,再目标空间里进行循环输出,并且不改变源空间的字符串

#define  _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
int main()
{
	char s[] = "[email protected]";//字符串
	char* p = "@.";//分隔符
	char buf[100] = { 0 };
	strcpy(buf, s);
	char* r = NULL;
	for (r = strtok(s, p); r != NULL; r = strtok(NULL, p))
	{
		printf("%s\n", r);
	}
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第33张图片

12. strerror函数的使⽤

char * strerror ( int errnum );

strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来

在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明的,C语⾔程序启动的时候就会使⽤⼀个全局的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会将对应的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。

在 C语言的库函数中设计了一些错误码,当我们库函数在调用的过程中发生的各种错误,要记录下来,这时候记录的就是错误码
例如:404———>该网页不存在

12.1 使用举例

#define  _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		char* ret = strerror(i);
		printf("%d:%s\n", i, ret);
	}
	return 0;
}

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第34张图片

但是,我们怎么知道代码运行失败的原因是什么呢?

我们可以举个例子,来看看库函数在C语言中的作用,也可以看看错误的原因是什么

当库函数调用失败的时候,会将错误码记录到errno这个变量中

errno是C语言的一个全局变量

例如,我们要读取一个文件,读取文件前,我们要打开文件,打开成功,前提是文件存在,反之,则打开失败

我们看一下界面:

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第35张图片

我想读区test_9_7这个文件,看看我们能不能成功

#include
#include
#include
#include
int main()
{
	FILE* pf = fopen("test_9_7", "r");
	if (pf == NULL)
	{
		printf("打开文件失败,失败的原因是:%s\n", strerror(errno));
		return 1;
	}
	else
	{
		printf("打开文件成功\n");
	}
	return 0;
}

虽然我们看到了错误原因,但是为什么打开失败呢?明明我的界面上就有这个文件啊!

那是因为,我们没有显示文件拓展名

通过拓展名,我们发现原来我们输入的文件名不对

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第36张图片

这样之后,就可以打开成功了

12.2 相关函数perror的使用

perror函数是打印错误信息的

#include 
#include 
#include 
int main ()
{
 FILE * pFile;
 pFile = fopen ("unexist.ent","r");
 if (pFile == NULL)
 perror("Error opening file unexist.ent");
 return 0;
}

本次的分享到这里就结束了!!!

PS:小江目前只是个新手小白。欢迎大家在评论区讨论哦!有问题也可以讨论的!

如果对你有帮助的话,记得点赞+收藏⭐️+关注➕

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!_第37张图片

你可能感兴趣的:(算法,c语言,字符串函数和字符函数)