• C语言关于自定义字符函数和字符串函数的相关笔试题(找工作必看)


    本篇字符函数和字符串函数

    求字符串长度 strlen

    长度不受限制的字符串函数 strcpy strcat strcmp

    长度受限制的字符串函数介绍 strncpy strncat strncmp

    字符串查找 strstr strtok

    错误信息报告 strerror

    内存操作函数 memcpy memmove memset memcmp

    在我们笔试时,很有可能会让我们自己写这样的库函数,所以我们必须明白这些函数的用法以及如何自己写出这样的函数。


    1.strlen函数及模拟实现

    1.1用法

    字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包 含 ‘\0’ )。

    用法举例:

    #define _CRT_SECURE_NO_WARNINGS 1
    #include 
    int main()
    {
    	const char* str1 = "abcdef";
    	int ret = strlen(str1);
    	printf("%d", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    我们可以看到输出就是6,用来计算字符串中 ‘\0’ 前面出现的字符个数。

    1.2模拟实现

    //方法1,计数器方式
    int my_strlen(const char * str)
    {
    int count = 0;
    while(*str)
    {
    count++;
    str++;
    }
    return count;
    }
    
    //方法2,递归函数
    int my_strlen(const char * str)
    {
    if(*str == '\0')
    return 0;
    else
    return 1+my_strlen(str+1);
    }
    
    //方法3,指针-指针的方式
    int my_strlen(char *s)
    {
    char *p = s;
    while(*p != ‘\0)
    p++;
    return p-s;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    2.strcpy函数及模拟实现

    2.1用法

    源字符串必须以 ‘\0’ 结束。其会将源字符串中的 ‘\0’ 拷贝到目标空间。

    用法举例:

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

    2.2模拟实现

    char* my_strcpy(char* arr1,char* arr2)
    {
    	char* ret = arr1;
    	assert(arr1 != NULL);
    	assert(arr2 != NULL);
    	while (*arr2!='\0')
    	{
    		*arr1 = *arr2;
    		arr1++;
    		arr2++;
    	}
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.strcat函数及模拟实现

    3.1用法

    追加字符串,把一个字符串放到另一个字符串后面

    用法举例:

    int main()
    {
    	char arr1[30] = "shuaige,and,";
    	char arr2[] = "meinv";
    	printf("%s",strcat(arr1, arr2));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    3.2模拟实现

    char* my_strcat(char* arr1, char* arr2)
    {
    	char* ret = arr1;
    	assert((arr1 && arr2) != NULL);
    	while (*arr1 != '\0')
    	{
    		arr1++;
    	}
    	while (*arr2 != '\0')
    	{
    		*arr1 = *arr2;
    		arr1++;
    		arr2++;
    	}
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4.strstr函数及模拟实现

    4.1用法

    返回arr1中arr2第一次出现的位置,如果arr1中没有arr2,就返回NULL

    用法举例:

    int main()
    {
    	char arr1[] = "abbbcdef";
    	char arr2[] = "bbc";
    	char* ret = strstr(arr1, arr2);
    	if (ret == NULL)
    	{
    		printf("找不到哦");
    	}
    	else
    	{
    		printf("%s", ret);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    4.2模拟实现

    my_strstr(char* arr1, char* arr2)
    {
    	char* record;//记录开始匹配的位置
    	char* s1;//变利arr1指向的字符串
    	char* s2;//变利arr2指向的字符串
    	assert((arr1 && arr2) != NULL);
    	if (*arr2 == '\0')
    		return arr1;
    	record = arr1;
    	while (*record != '\0')
    	{
    		s1 = record;
    		s2 = arr2;
    		while ((*s1 && *s2 && (*s1 == *s2)) != '\0')
    		{
    			s1++;
    			s2++;
    		}
    		if (*s2 == '\0')
    			return record;
    			record++;
    	}
    	return NULL;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    5.strcmp函数及模拟实现

    5.1用法

    比较两个字符串的大小(按位比较,也就是一位一位比较)
    第一个字符串大于第二个字符串,则返回大于0的数字
    第一个字符串等于第二个字符串,则返回0
    第一个字符串小于第二个字符串,则返回小于0的数字

    用法举例:

    int main()
    {
    	char arr1[] = "abc";
    	char arr2[] = "abd";
    	int ret = strcpy(arr1, arr2);
    	if (ret>0)
    	printf("arr1大");
    	else if (ret=0)
    	printf("一样大");
    	else 
    	printf("arr2大");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    5.2模拟实现

    my_strcpy(char* arr1, char* arr2)
    {
    	assert((arr1 && arr2) != NULL);
    	while (*arr1 == *arr2)
    	{
    		if (*arr1 == '\0')
    			return 0;
    		arr1++;
    		arr2++;
    	}
    	if (*arr1 > *arr2)
    		return 1;
    	else
    		return -1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    6.memcpy函数及模拟实现

    6.1用法

    拷贝数据,数据不重叠,即将一个数组拷贝到另一个不相干的数组。不能实现将一个数组拷贝到这个数组本身。

    用法举例:

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

    在这里插入图片描述

    6.2模拟实现

    void* my_memcpy(void* arr1, void* arr2, int sz)
    {
    	void* ret = arr1;
    	assert((arr1 && arr2) != NULL);
    	while (sz != 0)
    	{
    		
    		*(char*) arr1 = *(char*) arr2;
    		arr1 = (char*)arr1 + 1;
    		arr2 = (char*)arr2 + 1;
    		sz--;
    	}
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    7.memmove函数及模拟实现

    7.1用法

    拷贝数据,数据重叠时也能做到。即相较于memcpy,可以实现将一个数组拷贝到这个数组本身。

    用法举例:

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

    在这里插入图片描述

    7.2模拟实现

    void* my_memmove(void* arr1, const void* arr2, size_t sz)
    {
    	assert((arr1 && arr2) != NULL);
    	void* ret = arr1;
    	if (arr1 < arr2)
    	{
    		while (sz != 0)
    		{
    			*(char*)arr1 = *(char*)arr2;
    			arr1 = (char*)arr1 + 1;
    			arr2 = (char*)arr2 + 1;
    			sz--;
    		}
    	}
    	else
    	{
    		while (sz!=0)
    		{
    			sz--;
    			*((char*)arr1 + sz) = *((char*)arr2 + sz);
    		}
    	}
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    8. 其他字符函数和字符串函数

    提示:其他函数没有那么重要,这里只简单说明用法,不再进行模拟实现!

    8.1strncpy

    8.1.1 strncpy用法

    相较于strcpy,其可以自定义拷贝多少个字符。

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

    在这里插入图片描述

    8.1.2 strncpy模拟实现

    char* my_strncpy(char* arr1, char* arr2,int num)
    {
    	char* ret = arr1;
    	assert(arr1 != NULL);
    	assert(arr2 != NULL);
    	while ((num--) != 0)
    	{
    		if (*arr2 == '\0')
    		{
    			*arr1++ = '\0';
    		}
    		else
    		{
    			*arr1 = *arr2;
    			arr1++;
    			arr2++;
    		}
    	
    	}
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    8.2strncat

    8.2.1 strncat用法

    相较于strcat,可以自定义在后面拷贝多少个字符。

    int main()
    {
    	char arr1[20] = "abc\0xxxxxxxxxxxxxx";
    	char arr2[] = "defghi";
    	strncat(arr1, arr2, 5);
    	printf("%s\n", arr1);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    8.2.2strncat模拟实现

    char* my_strncat(char* arr1, char* arr2,int num)
    {
    	char* ret = arr1;
    	assert((arr1 && arr2) != NULL);
    	while (*arr1 != '\0')
    	{
    		arr1++;
    	}
    		while ((num--) != 0)
    	{
    		if (*arr2 == '\0')
    		{
    			*arr1++ = '\0';
    		}
    		else
    		{
    			*arr1 = *arr2;
    			arr1++;
    			arr2++;
    		}
    	
    	}
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    8.3strncmp

    相较于strcmp,可以指定比较多少个字符。

    int main()
    {
    	char arr1[] = "abczef";
    	char arr2[] = "abcqw";
    	
    	int ret = strncmp(arr1, arr2, 4);
    	printf("%d\n", ret);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    8.4字符分类函数

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

    8.5strock

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

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

    int main()
    {
    	char arr[] = "dashuaige@yeah.net@hehe.haha";
    	char arr2[] = "192.168.23.101";
    
    	char buf1[200] = { 0 };//"zpengwei\0yeah.net"
    	strcpy(buf1, arr);
    
    	char buf2[200] = { 0 };//"192.168.23.101"
    	strcpy(buf2, arr2);
    
    	char* p = "@.";
    	char* s = NULL;
    	for (s = strtok(buf1, p); s != NULL; s=strtok(NULL, p))
    	{
    		printf("%s\n", s);
    	}
    
    	char* p2 = ".";
    	for (s = strtok(buf2, p2); s != NULL; s = strtok(NULL, p2))
    	{
    		printf("%s\n", s);
    	}
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述

  • 相关阅读:
    澳洲谷揽GRANAR谷物分析仪维修GR-1800蛋白检测仪
    MySQL高可用
    代码随想录day11 150. 逆波兰表达式求值 、 239. 滑动窗口最大值 、 347.前 K 个高频元素
    游戏开发30课 cocoscreator骨骼贴图布局设置
    【Try to Hack】vulhub靶场搭建
    编译llvm-embedded-toolchain-for-Arm-main
    参考线平滑-FemPosDeviation-OSQP
    java.swing 飞机大战小游戏
    day008--mysql中的字符串函数
    Ros1 学习12- tf坐标系广播与监听的编程实现
  • 原文地址:https://blog.csdn.net/qq_57425280/article/details/133131908