字符和字符串函数介绍(二)

目录

1.1strerror

1.11perro(打印错误信息的函数)

1.2memcpy(内存拷贝函数)

1.3mommove(字符串拷贝函数) 

14memcmp(内存比较函数)

​编辑

1.5memset(内存设置函数)

1.6字符分类函数和字符转换函数:

总结


1.字符和字符串函数介绍

1.1strerror

字符和字符串函数介绍(二)_第1张图片

函数介绍:C语言的库函数在运行的时候,如果发生错误,就会将错误码放在一个变量中,这个变量就是errnum,这些错误码是一些数字:1、2、3、4、5等,编译器将错误码翻译成错误信息。(注意:使用errnum变量要包含头文件#include)
strerror函数转译的一些错误信息:

#include
#include
#include
int main()
{
	printf("%s\n", strerror(1));
	printf("%s\n", strerror(2));
	printf("%s\n", strerror(3));
	printf("%s\n", strerror(4));
	printf("%s\n", strerror(5));
	printf("%s\n", strerror(6));
	printf("%s\n", strerror(7));
	return 0;
}

字符和字符串函数介绍(二)_第2张图片strerro函数的使用案例:

#include
#include
#include
int main()
{
	FILE* fp = fopen("d:\\test.txt", "r");//以读取的方式打开文件的函数
	if (fp == NULL)
	{
		printf("%s", strerror(errno));
	}
	fclose(fp);
	return 0;
}

字符和字符串函数介绍(二)_第3张图片

1.11perror(打印错误信息的函数)

void perror(const char* str);

字符和字符串函数介绍(二)_第4张图片

函数介绍:①将errno的值解释为错误信息,并输出到控制台,在错误信息前面可添加str指定的自定义的消息。

②errno是一个整型变量,其值描述了对库函数的调用所产生的错条件或诊断信息(C标准库的任何函数都可以为errno设置值,即使在该引用中未明确指定,并且即使没有发生错误),有关详细信息请阅读errno。

③perror生成的错误消息取决于平台。

④如果参数str不是空指针,则会打印str,后面跟着冒号(:)和空格:无论str是否为空指针,生成的错误信息都会被打印出来,后跟一个换行符(\n)。

⑤在错误信息调用后立即调用perror,否则它会被其他函数覆盖。

参数介绍:包含在错误信息本身之前打印的自定义消息的C字符串。如果它是空指针,则不会打印前面的自定义消息,但仍会打印错误消息。按照惯例,应用程序本身的名称通常作为参数。

注意:perror函数头文件包含在#include里面

perror函数的使用案例:

#include
#include
#include
int main()
{
	FILE* fp = fopen("d:\\test.txt", "r");//以读取的方式打开文件的函数
	if (fp == NULL)
	{
		//printf("%s", strerror(errno));
		perror("fopen");
	}
	fclose(fp);
	return 0;
}

在上一段代码中,fopen(“d:\\test.txt","r")执行的是以读取的方式打开"test.txt"文件的函数,如果文件不存在会返回空指针,这时执行出现错误strerror函数得到错误码,用printf将其打印出来,以方便程序员检查修改代码。类比perror函数功能,相当于printf函数和strerror函数的结合,报错信息中会出现自定义信息fopen。

1.2memcpy(内存拷贝函数)

void * memcpy(void * destination,const void*source,size_num);

字符和字符串函数介绍(二)_第5张图片

 函数介绍:

①函数从source的位置开始向后复制num个字节的数据到destnation的内存位置。

②这个函数在遇到'\0'的时候并不会停下来。

③如果source和destnation有任何的重叠,复制的结果都是未定义的。

注意:num应设置成打印类型字节数的整数倍

memcpy函数的使用案例:

#include
#include
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	memcpy(arr2, arr1, 40);
	return 0;
}

memcpy函数执行之前的时候,arr2数组的内容:

字符和字符串函数介绍(二)_第6张图片

memcpy函数执行之后的时候,arr2数组的内容:

字符和字符串函数介绍(二)_第7张图片

 模拟实现memcpy函数:

#include
#include
void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	while (num--)
	{
		*(char*)dest =*(char*) src;
		(char*)dest=(char*)dest+1;
		(char*)src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	my_memcpy(arr2, arr1, 40);
	return 0;
}

字符和字符串函数介绍(二)_第8张图片

 字符和字符串函数介绍(二)_第9张图片

当源字符串和目标字符串有重叠部分的时候(即拷贝的源字符串内容和目标空间在同一字符串时),由于memcpy函数从前向后拷贝的,同一字符串前面的字符把后面的字符覆盖了可能达不到我们想要效果,下面我们将要介绍另一个可以解决该问题的mommovce函数。

1.3mommove(字符串拷贝函数) 

      void*memmove(void*destination,const void*source,size_t num

字符和字符串函数介绍(二)_第10张图片

 函数介绍:

和memcpy的差别就是memmove函数处理的原内存块和目标是可以重叠的

函数的使用案例1(在同一字符串中目的空间首地址dest小于首地址src):

#include
#include
int main()
{
	//源字符串首地址src,目标空间首地址dest
	//当dest

 执行之前:字符和字符串函数介绍(二)_第11张图片

执行之后:

字符和字符串函数介绍(二)_第12张图片

函数的使用案例2(在同一字符串中目的空间首地址dest大于等于源字符串首地址src):

#include
#include
int main()
{
	//源字符串首地址src,目标空间首地址dest
	//当dest>=src时
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1+5, arr1+2, 20);
	return 0;
}

执行之前:

字符和字符串函数介绍(二)_第13张图片

执行之后: 

字符和字符串函数介绍(二)_第14张图片

 memmove函数原理:

字符和字符串函数介绍(二)_第15张图片

模拟实现memmove函数:

void* my_memmove(void *dest,const void* src,size_t num)
{
	assert(dest && src);
	void* ret = dest;
	if (src > dest)
	{
		//前-->后
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{//后-->前
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1+2, arr1 , 20);
	return 0;
}

注意:在VS编译器下,memcpy函数重叠时出现的bug已经被完善,memcpy函数与memmove函数的功能一样,但在其他编译器下memcpy函数不一定被完善,好奇的朋友们可以自行尝试一下。

14memcmp(内存比较函数)

           int memcmp(const void *ptr1,const void * ptr2) ;  

字符和字符串函数介绍(二)_第16张图片

函数介绍:由ptr1指向内存块的前num个字节与ptr2指向内存块的前num个字节,如果相同,返回0;如果两个内存块中不相同的第一个字节在ptr1的值大于ptr2的值,返回大于0的值;如果两个内存块中不相同的第一个字节在ptr1的值小于ptr2的值,返回小于0的值(注意:与strcmp函数不同遇到‘\0',不会停止)。

 memcmp函数的使用案例:

#include
#include
int main()
{
	int arr1[] = { 1,2,3 };
	//01 00 00 00 02 00 00 00 03 00 00 00
	int arr2[] = { 1,2,6 };
	//01 00 00 00 02 00 00 00 06 00 00 00
	int ret=memcmp(arr1, arr2, 12);
	printf("%d", ret);
	return 0;
}

字符和字符串函数介绍(二)_第17张图片

1.5memset(内存设置函数)

             void * memset(void * ptr,int value,size_t num);

字符和字符串函数介绍(二)_第18张图片 函数介绍:由ptr指向的内存代码块前num个字节数被设置指定值,其中ptr为指向代码块的指针,value为int类型的设置值,num为unsigned类型的字节数,返回ptr的参数。

memset的使用案例:

#include
#include
int main()
{
	int arr1[] = { 1,2,3 };
	//函数设置之前
	//01 00 00 00 ,02 00 00 00, 03 00 00 00
	memset(arr1, 1, 12);
	//函数设置之后
	//01 01 01 01 ,01 01 01 01 ,01 01 01 01
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("%d\n", arr1[1]);
	}
	return 0;
}

字符和字符串函数介绍(二)_第19张图片字符和字符串函数介绍(二)_第20张图片

 字符和字符串函数介绍(二)_第21张图片

 memset函数也可以设置字符数组,拥有与strcpy函数类似的功能

#include
#include
int main()
{
	char arr1[] = "hello wrold";
	memset(arr1, 'x', 5);
	printf("%s\n", arr1);
	memset(arr1 + 6, 'y', 5);
	printf("%s\n", arr1);
	return 0;
}

字符和字符串函数介绍(二)_第22张图片

1.6字符分类函数和字符转换函数:

字符分类函数:

函数 如果它的参数符合下列条件返回真
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页'\f',换行‘\n',回车'\r',制表符'\t'或者垂直制表符'\v'
isdigit 十进制数字0-9
isxdigit 十六进制数字,包括所有十进制数字,小写字母a-f,大写字母A-F
islower 小写字母a-z
isupper 大写字母A-Z
isalpha 字母a-z或A-Z
isalnum 字母或者数字,a-z,A-Z,0-9
ispunct 标点符号,任何不属于数字或则字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符

字符转换函数:

函数 函数介绍
tolower 如果转换的字符是大写字母并且具有小写等写值,则转换为小写字母
toupper 如果转换的字符是小写字母并且具有大写等写值,则转换为大写字母

字符分类函数和字符转换函数包含在头文件#include中,以上是其相关的用法,好奇的朋友们可以尝试探索一下。

总结

本篇承接上一篇博客:字符函数和字符串函数​​​​​​​介绍了strerror、perror、memcpy、mommove、memcmp、memset、字符分类函数和字符转换函数。到现在字符和字符串主要的相关函数已经介绍完毕,希望对大家认识字符和字符串函数有些许帮助,如有不对,敬请指正!最后,祝大家在新的一年里好远成,学习成绩飞猛进!

你可能感兴趣的:(C语言进阶,c语言)