• 字符函数和字符串函数(上)


    感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
    🐒🐒🐒个人主页
    🥸🥸🥸C语言
    🐿️🐿️🐿️C语言例题
    🐣🐓🏀python

    字符分类函数

    C语言中有一系列的函数是专门做字符分类的,也就是一个字符是属于什么类型的字符的。
    这些函数的使用都需要包含一个头文件是ctype.h
    这些函数的使用方法非常类似,我们就讲解一个函数的事情,其他的非常类似:

     int islower ( int c );
    
    • 1

    islower 是能够判断参数部分的c是否是小写字母的。
    通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0。
    我们举个例子来演示一下:写一个代码,将字符串中的小写字母转大写,其他字符不变。

    #include 
    #include 
    int main()
    {
    	int i = 0;
    	char str[] = "Test String.\n";
    	char c;
    	while (str[i])
    	{
    		c = str[i];
    		if (islower(c))
    			c -= 32;//依据ASCLL码表进行的计算
    		putchar(c);
    		i++;
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    解析:
    str是一个数组,数组里的元素是一个字符串,while(str[i])是为了判断str[i]是否为\0,如果不是\0就进行接下来的操作,否则就不执行while语句

    我们将str[i]的值赋给字符变量c,通过if语句用islower来判断c是否为小写字符,如果islower©返回的值为非0的数就是小写字母,否则就不是小写字母,因为if语句中括号内如果为非0就是真,所以会执行if语句,如果为0则为假,就不会执行if语句

    执行完后通过putchar输出字符c,再i++判断下一个字符

    字符转换函数

    C语言提供了2个字符转换函数:

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

    上面的代码,我们将小写转大写,是-32完成的效果,有了转换函数,就可以直接使用 tolower 函数。

    #include 
    #include 
    int main()
    {
    	int i = 0;
    	char str[] = "Test String.\n";
    	char c;
    	while (str[i])
    	{
    		c = str[i];
    		if (islower(c))
    			c = toupper(c);
    		putchar(c);
    		i++;
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    strlen(Get string length)的使用和模拟实现

    size_t strlen ( const char * str );
    
    • 1

    strlen模拟实现重点:
    1:字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中’\0’ 前面出现的字符个数(不包含 ‘\0’ )

    2:参数指向的字符串必须要以 ‘\0’ 结束

    3:注意函数的返回值为size_t,是无符号的( 易错 )

    模拟实现代码:

    法一(记录次数)
    int my_strlen(const char* str)
    {
    	int count = 0;
    	assert(str);
    	while (*str)
    	{
    		count++;
    		str++;
    	}
    	return count;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    解析:
    这个代码相对比较简单,我们设一个变量count=0,通过while循环,如果str没有到\0就str++

    然后用count++记录执行了多少次循环,当str是\0时,while括号内部就是0为假,就返回count

    法二(递归)
    int my_strlen(const char* str)
    {
    	assert(str);
    	if (*str == '\0')
    		return 0;
    	else
    		return 1 + my_strlen(str + 1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    解析:
    递归这里就比较难想到,assert断言判断s传入的指针是否有问题,这是一个好习惯

    通过if语句判断str是否为\0(这里就是限制条件),如果不是\0就返回1+my_strlen(str + 1)

    str+1就是为了接近限制条件*str==‘\0’,每加一次1就往后移动一个字符元素,知道为\0,最后回归,返回我们所需要的数

    法三(指针相减)
    int my_strlen(char* s)
    {
    	assert(str);
    	char* p = s;
    	while (*p != '\0')
    		p++;
    	return p - s;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    解析:
    指针相减也比较难想到,我们设一个字符指针p=s,p是s首元素的地址

    我们让p指向的地址一直往后移,直到是\0,这时我们通过指针相减,就能计算出相差多少个元素了

    strcpy(Copy string)的使用和模拟实现

    char* strcpy(char * destination, const char * source );
    
    • 1

    strcpy模拟实现重点:
    1:源字符串必须以 ‘\0’ 结束

    2:会将源字符串中的 ‘\0’ 拷贝到目标空间

    3:目标空间必须足够大,以确保能存放源字符串。

    4:目标空间必须可变

    我们对上面的重点解释一下
    strcpy是将一个字符串拷贝到另一个字符串,所以源字符串必须以\0结尾

    我们假设要拷贝进的字符串为a,另一个字符串为b,由于我们拷贝的目的是要让b中的字符完全和a相同,我们知道\0是一个字符串的结尾,当我们将a中的\0拷贝进去后,b后面的字符就相当于切断了,所以必须将源字符串中的\0拷贝进去

    当然了目标空间也一定要大,否则容纳不下a,就无法拷贝进去

    因为要拷贝进去,如果目标空间不可变那还拷贝什么

    代码示例:

    # include
    int main()
    {
    	char arr[7] = { "abc" };
    	char brr[] = { "def" };
    	strcat(arr, brr);
    	printf("%s", arr);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    拷贝过程如图:
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    strcpy的模拟实现

    //模拟实现需要注意的点
    //1.参数顺序
    //2.函数的功能,停⽌条件
    //3.assert
    //4.const修饰指针
    //5.函数返回值
    //题⽬出⾃《⾼质量C/C++编程》书籍最后的试题部分
    char* my_strcpy(char* dest, const char* src)
    {
    	char* ret = dest;
    	assert(dest != NULL);
    	assert(src != NULL);
    	while ((*dest++ = *src++))
    	{
    		;
    	}
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    解析:

    通过断言判断目标地址和需要拷贝进去的地址是否为空指针

    while循环括号中的部分就非常妙了,二者都是后置++,就是先用后++,使src的每个字符都拷贝进了dest

    strcat(Concatenate strings)的使用和模拟实现

    strcat模拟实现重点:

    1:源字符串必须以 ‘\0’ 结束

    2:目标字符串中也得有 \0 ,否则没办法知道追加从哪里开始

    3:目标空间必须有足够的大,能容纳下源字符串的内容

    4:目标空间必须可修改

    我们对上面的重点进行解释一下:
    追加字符串后我们会得到一个新的字符串,因为每个字符串都需要用\0来结尾,所以源字符串就需要以\0结尾

    追加字符串我们都是追加在目标字符串最末尾(也就是\0的位置),将需要追加的字符串替换\0就得到我们所需要的字符串

    如果目标空间不足够大的话我们追加的字符串就装不下,就会出问题

    因为追加就相当于改变目标空间的储存内容,所以目标空间必须可改变

    strcat的模拟实现:

    char* my_strcat(char* dest, const char* src)
    {
    	char* ret = dest;
    	assert(dest != NULL);
    	assert(src != NULL);
    	while (*dest)
    	{
    		dest++;
    	}
    	while ((*dest++ = *src++))
    	{
    		;
    	}
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    解析:

    第一个while循环是为了找到\0的位置,方便追加字符串

    第二个while其实就是将源字符串追加到目标字符串

    strcmp(Compare two strings)的使用和模拟实现

    strcmp模拟实现重点:
    第一个字符串大于第二个字符串,则返回大于0的数字

    第一个字符串等于第二个字符串,则返回0

    第一个字符串小于第二个字符串,则返回小于0的数字

    比较两个字符串中对应位置上字符ASCII码值的大小

    代码示例:

    # include
    int main()
    {
    	char arr[] = "abcdef";
    	char brr[] = "abq";
    	int  ret = strcmp(arr, brr);
    	printf("%d", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    我们可以看到<返回-1,>返回1,=返回0,但是在其他的编译器可能就不是这么返回的了,可能<返回-2…

    strcmp函数的模拟实现:

    int my_strcmp(const char* str1, const char* str2)
    {
    	int ret = 0;
    	assert(src != NULL);
    	assert(dest != NULL);
    	while (*str1 == *str2)
    	{
    		if (*str1 == '\0')
    			return 0;
    		str1++;
    		str2++;
    	}
    	return *str1 - *str2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    解析:

    我们需要分情况讨论
    1:如果一开始str1!=str2,我们其实就可以直接判断str1和str2直接的大小了(注意strcmp的比较是每个字符之间的比较,否则无法比较)

    2:如果一开始str1=str2,那么我们就可以通过str1++和str2++来进行判断下一个字符是否相等

    3:此外在(2)的基础上如果str1已经等于\0我们就没必要比较后面的字符了,直接返回0表示str1前面的字符和str2前面的字符相等

    4:如果不相等我们就返回两个字符相减(两字符相减我们可以通过ASCLL码计算)

  • 相关阅读:
    【通过】华为机试真题12 - 仿LISP运算
    Mysql-----Innodb引擎行锁变为表锁
    在国内购买GPT服务前的一定要注意!!!
    计算机毕业设计之java+javaweb的学生信息管理系统
    WebWall-03.XSS(跨站脚本漏洞)
    微信小程序 实现手写签名(横屏签名板)
    【知识网络分析】作者合作网络(Co-authorship)
    cmd命令行,杀掉某个进程,以(Anaconda为例)
    详细介绍 Oracle中的Materialized Views(物化视图/快照)
    一文理解Hadoop分布式存储和计算框架入门基础
  • 原文地址:https://blog.csdn.net/2301_79178723/article/details/133528322