• 【C语言】字符函数和字符串函数(含模拟)


    努力更新模拟实现中…

    前言:
    在做OJ题或阅读代码时或多或少会遇到一些字符函数和字符串函数,
    如果不认识或不熟悉就会造成不便,
    本篇文章主要是为了这方面而存在

    重点:

    重点介绍处理字符和字符串的库函数的使用和注意事项

    一一一一一一一一分割线一一一一一一一一一

    函数介绍(附模拟实现):

    注意:

    模拟实现没有全部囊括,只实现了大部分的字符函数(长度不受限制)和内存函数,实现在每个函数的末尾部分

    1.1 strlen

    注意:此图片与以下图片截图均来自cplusplus.com

    在这里插入图片描述

    我们可得这个函数是求在字符串开始与'\0'之间的字符串长度

    代码示例:

    #include 
    int main()
    {
    	const char* str1 = "abcdef";
    	const char* str2 = "bbb";
    	printf("%d\n", strlen(str1));
    	printf("%d\n", strlen(str2));
    	if (strlen(str2) - strlen(str1) > 0)
    	{
    		printf("str2>str1\n");
    	}
    	else
    	{
    		printf("srt1>str2\n");
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    结果:
    在这里插入图片描述
    解释:

    这里的6和3容易理解,那么str2>str1怎么解释?
    因为strlen返回值类型为size_t类型,为无符号整形
    即相减的结果虽然为一个负数,但负数的无符号整形显然是巨大的正数
    故大于

    此函数的注意事项:
    1.字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
    2.参数指向的字符串必须要以 ‘\0’ 结束。
    3.注意函数的返回值为size_t,是无符号的( 易错 )

    模拟实现strlen
    一一一一一一一一分割线一一一一一一一一一

    1.2 strcpy

    在这里插入图片描述

    我们可以知道此函数是为了拷贝字符串的

    代码示例:

    #include
    
    int main()
    {
    	char str1[20] = { 0 };
    	char str2[] = "hello world";
    	strcpy(str1, str2);
    	printf("%s\n", str1);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果:
    在这里插入图片描述

    此函数的注意事项:
    1.源字符串必须以 ‘\0’ 结束。
    2.会将源字符串中的 ‘\0’ 拷贝到目标空间。
    3.目标空间必须足够大,以确保能存放源字符串。
    4.目标空间必须可变。

    模拟实现strcpy
    一一一一一一一一分割线一一一一一一一一一

    1.3 strcat

    在这里插入图片描述

    上边两个函数很容易就可以根据形式看出大概意思,
    str代表字符串,那么cat代表什么?
    他代表Catenate,连接的缩写,也就是追加字符串的意思

    代码示例:

    int main()
    {
    	char str1[20] = "abc";
    	char str2[] = "dfg";
    	strcat(str1, str2);
    	printf("%s\n", str1);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:
    在这里插入图片描述

    此函数的注意事项:
    1.源字符串必须以 ‘\0’ 结束。
    2.目标空间必须有足够的大,能容纳下源字符串的内容。
    3.目标空间必须可修改。
    4.不可以自己追加自己。
    解释:关键在于 '\0',因为
    在这里插入图片描述

    模拟实现strcat

    一一一一一一一一分割线一一一一一一一一一

    1.4 strcmp

    在这里插入图片描述

    我们可以得出此函数是为为比较字符串函数

    代码示例:

    int main()
    {
    	char str1[] = "abb";
    	char str2[] = "abc";
    	int ret =strcmp(str1, str2);
    	printf("%d\n", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    此函数的注意事项:
    1.第一个字符串大于第二个字符串,则返回大于0的数字
    2.第一个字符串等于第二个字符串,则返回0
    3.第一个字符串小于第二个字符串,则返回小于0的数字
    4.比较字符串是从头开始逐一比较每个字符的ASCII码值,相等就继续向下比较,直到输出

    1.5 strncpy

    在这里插入图片描述

    与strcpy功能一致,
    但多了n,n代表num,也就意味着我们可以自由的输入想复制的个数

    代码示例:

    int main()
    {
    	char str[] = "xxxxxxxxxxx";
    	char str1[20] = { 0 };
    	printf("%s\n",strncpy(str1, str, 9));
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:
    在这里插入图片描述

    此函数的注意事项:
    1.拷贝num个字符从源字符串到目标空间。
    2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

    一一一一一一一一分割线一一一一一一一一一

    1.6 strncat

    在这里插入图片描述

    与strcat功能一致,
    但多了n,n代表num,也就意味着我们可以自由的输入想追加的个数

    代码示例:

    int main()
    {
    	char str1[20];
    	char str2[20];
    	strcpy(str1, "To be ");
    	strcpy(str2, "or not to be");
    	strncat(str1, str2, 6);
    	puts(str1);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果:
    在这里插入图片描述

    此函数的注意事项:
    1.追加后会在最后添加’\0’
    2.如果source中的C字符串的长度小于num,则只复制结束空字符之前的内容。

    一一一一一一一一分割线一一一一一一一一一

    1.7 strncmp

    在这里插入图片描述

    与strcmp功能一致,
    但多了n,n代表num,也就意味着我们可以自由的输入想比较的个数

    代码示例:

    int main()
    {
    	char str1[] = "abccc";
    	char str2[] = "abdd";
    	int ret = strncmp(str1, str2, 3);
    	printf("%d\n", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:
    在这里插入图片描述
    此函数的注意事项:

    比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

    一一一一一一一一分割线一一一一一一一一一

    1.8 strstr

    在这里插入图片描述

    可以看到此函数是用来寻找一个字符串中是否含有另一个字符串

    代码示例:

    int main()
    {
    	char str1[] = "abbbbcd";
    	char str2[] = "bbc";
    	char* ret = strstr(str1, str2);
    	printf("%s\n", ret);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果:
    在这里插入图片描述
    模拟实现strstr
    一一一一一一一一分割线一一一一一一一一一

    1.9 strtok

    在这里插入图片描述

    此函数是分割字符串的函数,依照你提供的sep字符串来进行分割

    代码示例:

    int main()
    {
    	char str[] = "zhangsan@tt.edu";
    	char* sep = "@.";
    	char* ret = NULL;
    	for (ret = strtok(str, sep); ret != NULL; ret=strtok(NULL, sep))
    	{
    		printf("%s\n", ret);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    结果:
    在这里插入图片描述

    函数的注意事项:
    1.sep参数是个字符串,定义了用作分隔符的字符集合
    2.第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
    3.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
    4.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
    5.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
    6.如果字符串中不存在更多的标记,则返回 NULL 指针。

    一一一一一一一一分割线一一一一一一一一一

    1.10 strerror

    在这里插入图片描述

    可以看到此函数可以理解为是一个错误解释函数,如果程序发生错误,会告诉你发生错误的原因

    代码示例:

    //假设我们没有创建次文件
    int main ()
    {
     FILE * pFile;
      pFile = fopen ("unexist.ent","r");
      if (pFile == NULL)
        printf ("打开文件失败: %s\n",strerror(errno));
        //errno: Last error number
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果:在这里插入图片描述

    一一一一一一一一分割线一一一一一一一一一

    1.11 memcpy

    在这里插入图片描述

    既然有字符穿拷贝函数,那么也会有内存拷贝函数,因为我们有时不仅要拷贝字符串,还要对一些整形之类的进行操作,于是就有了内存拷贝函数,而其中的size_t类型的num就是要操作的大小,单位是字节

    代码实现:

    int main()
    {
    	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    	int arr2[20] = { 0 };
    	memcpy(arr2, arr1, 12);
    	for (int i = 0; i < 10; i++)
    	{
    		printf("%d ", arr2[i]);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    代码示例:

    int main()
    {
    	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    	int arr2[20] = { 0 };
    	memcpy(arr2, arr1, 12);
    	for (int i = 0; i < 10; i++)
    	{
    		printf("%d ", arr2[i]);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果:
    在这里插入图片描述

    此函数的注意事项:
    1.函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
    2.这个函数在遇到 ‘\0’ 的时候并不会停下来。
    3.如果source和destination有任何的重叠,复制的结果都是未定义的。

    一一一一一一一一分割线一一一一一一一一一

    1.12 memmove

    在这里插入图片描述

    与memcpy如出一辙,只不过可以实现了内存重叠的操作

    代码示例:

    int main()
    {
    	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    	memcpy(arr1+2, arr1, 20);
    	for (int i = 0; i < 10; i++)
    	{
    		printf("%d ", arr1[i]);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果:
    在这里插入图片描述

    此函数的注意事项:
    1.和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
    2.如果源空间和目标空间出现重叠,就得使用memmove函数处理。

    一一一一一一一一分割线一一一一一一一一一

    1.13 memcmp

    在这里插入图片描述

    与strcmp大致相同,一个字节一个字节的比较,但不限于字符串

    代码示例:

    int main()
    {
    	int arr1[] = { 1,2,3,4,5 };
    	int arr2[] = { 1,2,2 };
    	int ret=memcmp(arr1, arr2, 12);
    	printf("%d\n", ret);
    	return 0l;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:在这里插入图片描述

    此函数的注意事项:
    比较从ptr1和ptr2指针开始的num个字节
    返回值如下: 在这里插入图片描述

    欢迎小伙伴的纠错与提问

  • 相关阅读:
    数据结构和算法
    Android大厂需要刷的(999道)面试题
    【博客506】k8s扩展调度器以支撑更灵活的GPU调度
    rust声明式宏
    【IDEA设置类注释】设置带作者和日期的类注释+设置方法注释包含返回值类型和参数
    Java设计模式(三)结构型 设计模式
    UE AIModule 源码解读之写法借鉴(一)
    m基于matlab的TDSCDMA系统性能仿真
    循环队列----数据结构
    除铜树脂-KF340
  • 原文地址:https://blog.csdn.net/2301_78636079/article/details/133140738