目录

一、字符分类函数

1.1islower和isupper

​编辑

1.2tolower和toupper

练习:写一个代码,将字符串中的大写字母转小写,其他字符不变。

           

二、字符串相关的函数

2.1strlen的使用和模拟实现

模拟实现strlen

2.2strcpy使用和模拟实现

2个错误案例:

模拟实现strcpy函数

2.3strcat使用和模拟实现

模拟实现strcat

2.4strcmp的使用和模拟实现

模拟实现strcmp

strncpy、strncat和strncmp


深入理解字符串函数和字符函数(二)-CSDN博客

一、字符分类函数

​C语言中有一系列的函数是专门做字符分类的,也就是一个字符是属于什么类型的字符的。​
这些函数的使用都需要包含一个头文件是 ctype.h

.

1.1islower和isupper

islower是能够判断参数部分的字符是否是小写字母的。​通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0。​

isupper是能够判断参数部分的字符是否是大写字母的。​通过返回值来说明是否是大写字母,如果是大写字母就返回非0的整数,如果不是大写字母,则返回0。​

int main()
{
	int ch = getchar();
	putchar(ch);
	if (islower(ch))
	{
		printf("小写\n");
	}
	else if (isupper(ch))
	{
		printf("大写\n");
	}

	return 0;
}

运行结果: 

    .           

1.2tolower和toupper

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

练习:
写一个代码,将字符串中的大写字母转小写,其他字符不变。

自己编写:

int main()
{
	char arr[] = "I Am A Atudent";
	int i = 0;
	while (arr[i])
	{
		if (isupper(arr[i]))
		{
			arr[i] = arr[i] + 32;
		}
		putchar(arr[i]);
		i++;
	}
	return 0;
}

运行结果: 

使用函数:

int main()
{
	char arr[] = "I Am A Atudent";
	int i = 0;
	while (arr[i])
	{
		if (isupper(arr[i]))
		{
			arr[i] = tolower(arr[i]); 
		}
		putchar(arr[i]);
		i++;
	}
	return 0;
}

其它的字符函数就不过多介绍了!下面开始字符串函数的详解!!!

           

二、字符串相关的函数

.

.

2.1strlen的使用和模拟实现

strlen的作用为计算字符串长度

关于strlen和sizeof的对比详见拙作:sizeof 和 strlen的对比及笔试题目-CSDN博客

int main()
{
	//char arr[] = "abcdef";//[a b c d e f \0]
	char arr[] = { 'a','b','c' };//[a,b,c]
	size_t len = strlen(arr);
	printf("%zd\n", len);// \0 位置不确定,随机值
	return 0;
}

strlen返回值为size_t类型的隐患,

例:3 - 6 = -3 ,但是size_t的类型会理解为一个非常大的一个正数

改进:把size_t强制转换为int类型

int main()
{
	//if (strlen("abc") - strlen("abcef") > 0)
	if ((int)strlen("abc") - (int)strlen("abcef") > 0)
	{
		printf("大于\n");
	}
	else {
		printf("小于等于\n");
	}

	return 0;
}
模拟实现strlen

此处有三种方法实现模拟

方法一:计数

size_t my_strlen1(const char* str)
{
	size_t count = 0;
	assert(str != NULL);
	while (*str != 0)
	{
		count++;
		str++;//让指针往后走一步
	}
	return count;
}

方法二:使用指针

size_t my_strlen2(const char* str)
{
	assert(str);
	char* start = str;
	while (*str != '\0')
		//while(*str)
	{
		str++;
	}
	return str - start;
}

不能创建临时变量计数器

方法三:递归

size_t my_strlen3(const char* str)
{
	if (*str == '\0')
	{
		return 0;//'\0'之前停止
	}
	else {
		return 1 + my_strlen3(str + 1);
	}
}

递归思想如图所示:

.

.

2.2strcpy使用和模拟实现

strcpy的作用为拷贝字符串

正常使用:

int main()
{
	char arr1[20] = "XXXXXXXXXX";
	//char arr2[] = { 'a','b','c' };//没有\0,一直输出
	char arr2[] = { 'a','b','c','\0'};
	strcpy(arr1, arr2);
	printf("%s\n", arr1);

	char arr3[20] = "XXXXXXXXXX";
	char arr4[] = "hello";
	strcpy(arr3, arr4);
	printf("%s\n", arr3);

	return 0;
}

运行结果: 

2个错误案例:

模拟实现strcpy函数
char* my_strcpy(char* dest, char* src)
{
	/*assert(dest != NULL);
	assert(src != NULL);*/
	char* ret = dest;
	assert(dest && src);
	while (*dest++ = *src++);
	/*{
		;
	}*/
	return ret;//返回目标空间的起始地址
}
 
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "abcdef";
	int t = my_strcpy(arr1, arr2);
	printf("%s\n",arr1);
	printf("%s\n",t);

	return 0;
}

my_strcpy函数接受两个参数:一个目标字符串(dest)和一个源字符串(src)。

在函数内部,首先使用char* ret来指向目标字符串(dest)的起始地址。

再用assert宏来断言目标字符串(dest)和源字符串(src)都不为空。如果它们为空,程序会在这里终止。

接下来,使用while循环遍历源字符串(src),并将每个字符逐个复制到目标字符串(dest)中,直到遇到空字符'\0'为止。

最后,返回指向目标字符串(dest)起始地址的指针ret。

使用案例:

.

.

2.3strcat使用和模拟实现

strcat的作用为在字符串后面追加字符串

注意事项:

返回值是目标空间的地址

字符串无法追加自身

字符串追加可以理解为:

找到目标字符串末尾的 ‘\0’后追加(其本质就是字符串拷贝)

使用案例:

原目标空间中一定要有\0,否则不知道从哪里开始追加

模拟实现strcat
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest && src);
	//1.找到目标空间的\0
	while (*dest)
	{
		dest++;
	}
	//2.拷贝
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}


int main()
{
	char arr1[20] = "hello";
	//原目标空间中一定要有\0,否则不知道从哪里开始追加
	char arr2[] = "world";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);//hello world

	return 0;
}

思路与strcpy相同!!!

模拟后的缺陷:

没有办法追加自身,但是库函数可以

char* my_strcat(char* dest, const char* src)
//缺陷:不能给自己追加
{
	char* ret = dest;
	assert(dest && src);
	//1.找到目标空间的\0
	while (*dest)
	{
		dest++;
	}
	//2.拷贝
	while (*dest = *src++)
	{
		;
	}
	return ret;
}


int main()
{
	char arr1[20] = "hello";
	//原目标空间中一定要有\0,否则不知道从哪里开始追加
	//my_strcat(arr1, arr1);//缺陷:不能给自己追加
	strcat(arr1, arr1);//但是库函数可以
	printf("%s\n", arr1);//hello

	return 0;
}

 .

 .                                                                                                                                .

2.4strcmp的使用和模拟实现

strcmp的作用为比较两个字符串

使用:

模拟实现strcmp

函数的实现方式是逐个字符比较两个字符串,直到遇到不相等的字符或者到达字符串的结尾\0。

如果两个字符串完全相等,函数返回0。如果s1在字典顺序上小于s2,则返回一个负数。如果s1在字典顺序上大于s2,则返回一个正数。

int my_strcmp(const char* s1, const char* s2)
{
	while (*s1 == *s2)
	{
		if (*s1 == '\0')
			return 0;
		s1++;
		s2++;
	}
	return *s1 - *s2;
}

int main()
{
	int ret = my_strcmp("bbp", "abcdef");
	if (ret > 0)
	{
		printf("大于\n");
	}
	else if (ret == 0)
	{
		printf("等于\n");
	}
	else {
		printf("小于\n");
	}

	return 0;
}

 

运行结果: 

strncpy、strncat和strncmp

  • 类比strcmp函数,不过多了一个参数----->要比较几个字符的个数

  • 类比strncat函数,不过多了一个参数----->要追加几个字符的个数

  • 类比strcpy函数, 不过多了一个参数----->要拷贝几个字符的个数

如果你感觉上述的代码对你有帮助,可以给我点个赞吗?

创作不易,谢谢各位的观看,咱们下期见!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐