目录
1.1strerror
1.11perro(打印错误信息的函数)
1.2memcpy(内存拷贝函数)
1.3mommove(字符串拷贝函数)
14memcmp(内存比较函数)
编辑
1.5memset(内存设置函数)
1.6字符分类函数和字符转换函数:
总结
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;
}
#include
#include
#include
int main()
{
FILE* fp = fopen("d:\\test.txt", "r");//以读取的方式打开文件的函数
if (fp == NULL)
{
printf("%s", strerror(errno));
}
fclose(fp);
return 0;
}
void perror(const char* str);
函数介绍:①将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。
void * memcpy(void * destination,const void*source,size_num); |
函数介绍:
①函数从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数组的内容:
memcpy函数执行之后的时候,arr2数组的内容:
模拟实现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;
}
当源字符串和目标字符串有重叠部分的时候(即拷贝的源字符串内容和目标空间在同一字符串时),由于memcpy函数从前向后拷贝的,同一字符串前面的字符把后面的字符覆盖了可能达不到我们想要效果,下面我们将要介绍另一个可以解决该问题的mommovce函数。
void*memmove(void*destination,const void*source,size_t num |
函数介绍:
和memcpy的差别就是memmove函数处理的原内存块和目标是可以重叠的
函数的使用案例1(在同一字符串中目的空间首地址dest小于首地址src):
#include
#include
int main()
{
//源字符串首地址src,目标空间首地址dest
//当dest
执行之后:
函数的使用案例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;
}
执行之前:
执行之后:
memmove函数原理:
模拟实现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函数不一定被完善,好奇的朋友们可以自行尝试一下。
int memcmp(const void *ptr1,const void * ptr2) ; |
函数介绍:由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;
}
void * memset(void * ptr,int value,size_t num); |
函数介绍:由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;
}
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;
}
字符分类函数:
函数 | 如果它的参数符合下列条件返回真 |
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、字符分类函数和字符转换函数。到现在字符和字符串主要的相关函数已经介绍完毕,希望对大家认识字符和字符串函数有些许帮助,如有不对,敬请指正!最后,祝大家在新的一年里好远成兔,学习成绩兔飞猛进!