C语言——字符函数和字符串函数(上)

引言

我们在学习C语言的过程中,我们经常遇上要对字符和字符串处理的情况,为了方便我们对字符和字符串进行操作,C语言标准库提供了一系列库函数。

今天我们来学习一下

字符函数

字符分类函数

C语言中的字符函数主要用于处理单个字符,这些函数在<ctype.h>头文件中定义。

以下是比较常用的字符分类函数:

函数 如果它的参数符合条件就返回真
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 字母或者数字,z~z,A~Z,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符

ps:控制字符指的是具有特殊的含义,它们不会被直接打印出来,而是用来执行特定的操作的字符,例如\n、\0

这些函数的使用方法类似,我们来看其中一个:

int islower(int c);

islower能够判断参数部分的c是否为小写字母

通过返回值来说明c是否为小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0

练习:

实现字符串的小写字母转换为大写,其他字符不变

#include <stdio.h>
#include<ctype.h>

int main()
{
	int i = 0;
	char str[] = "Hello World!\n";
	char c;
	while (str[i])
	{
        c = str[i];
		if (islower(c))    //使用 islower 函数检查 c 是否为小写字母	
		{
			c -= 32;       //在ASCII编码中,大写字母与小写字母之间的差值为32
		}
		putchar(c);
		i++;
	}
	return 0;
}

字符转换函数

C语言提供了字符转换函数,用于将字符从一种形式转换为另一种形式:

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

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

例如,toupper函数可以将小写字母转换为大写字母,而tolower函数可以将大写字母转换为小写字母。在之前的例子中,我们将小写字母转换为大写字母是通过减去32的ASCII码值来实现的,这是一种手动的方式。现在有了toupper函数,我们可以更直接地将小写字母转换为大写字母,而无需手动计算。

#include <stdio.h>
#include<ctype.h>

int main()
{
	int i = 0;
	char str[] = "Hello World!\n";
	char c;
	while (str[i])
	{
		c = str[i];
		if (islower(c))
		{
			c = toupper(c);
		}
		putchar(c);
		i++;
	}
	return 0;
}

字符串函数

strlen

1.strlen的用法

在使用字符串时,经常需要动态获取字符串长度,虽然可以通过循环来计算字符串长度,但是相当的麻烦。我们可以使用strlen函数来获取字符串长度。

其函数原型如下:

size_t strlen(const char *str);

注意:

str为要计算长度的字符串

字符串以'\0'作为结束标志,strlen函数返回的是在字符串中的'\0'前面出现的字符个数(不包括'\0')

返回值为size_t(无符号)

2.strlen的使用

strlen的使用十分简单,看个例子就能明白:

#include<stdio.h>
#include<string.h>

int main()
{
	char arr[] = "abcdef";
	int len = strlen(arr);
	printf("%d\n", len);
	return 0;
}

输出结果为:6

3.strlen的模拟实现

现在我们已经知道strlen的用法,接下来我们可以试着来模拟实现strlen

我们可以用以下三个方法:

3.1 计数器

思路:通过遍历字符串并计数,直到遇到结束符 '\0',从而得到字符串的长度。

代码如下:

int my_strlen(const char* p)  
{  
    int count = 0;
    assert(p);
    while (*p)     
    {  
        p++;       //将指针移动到下一个字符  
        count++;   //计数器加1,表示已经遍历过一个字符  
    }  
    return count;  // 返回计算得到的字符串长度  
}  
  
int main()  
{  
    char arr[] = "abcdef";  
    int len = my_strlen(arr); 
    printf("%d\n", len); 
    return 0; 
}
3.2 递归

思路:通过不断调用自身处理字符串的下一个字符,直到遇到结束符 '\0',每次递归返回当前字符长度加上剩余字符串长度,从而得到整个字符串的长度。

代码如下:

int my_strlen(char* p)
{
	if (*p != '\0')
	{
        //如果不是结束符,则递归调用my_strlen函数,并将指针p加1指向下一个字符  
		return 1 + my_strlen(p + 1);    // 每次调用p+1指向下一个元素  
	}
	else
	{
		return 0;//结束递归
	}
}

int main()
{
	char str[] = "abcdef";
	int len = my_strlen(str);
	printf("%d\n", len);
	return 0;
}
3.3 指针-指针

在指针的学习中,我们知道指针-指针得到的是两个指针中间的元素个数

思路:使用两个指针,一个用于遍历字符串,另一个作为起始点,通过计算两个指针之间的偏移量来得到字符串的长度

代码如下:

int my_strlen(char* p1)
{
	char* p2 = p1;//使两个指针都指向首元素
	while (*p2)
	{
		p2++;
	}
	return p2 - p1;//返回两指针之间的元素的个数就是其长度
}

int main()
{
	char str[] = "abcdef";
	int len = my_strlen(str);
	printf("%d\n", len);
	return 0;
}

strcpy

1.strcpy的用法

在字符串操作中,字符串复制是比较常见的操作,对于字符数组,无法使用赋值号“=”将一个字符串常量或其他表示字符串的字符串的字符数组或字符指针赋值给它,这个时候就可以使用strcpy来完成此项任务,该函数的原型如下:

char *strcpy(char *dest, const char *src);

注意:

源字符串必须以'\0'结束

该函数会将源字符串中的'\0'拷贝到目标空间

目标空间必须足够大,确保能放下源字符串

目标空间必须可以修改

2.strcpy的使用

#include <stdio.h>
#include <string.h>

int main()
{
	char str1[20] ;
	char str2[20] = "hello world";
	strcpy(str1, str2);
	printf("%s\n", str1);
	return 0;
}

输出结果为:hello world

3.strcpy的模拟实现

思路:通过自定义的 my_strcpy 函数,将源字符串 str2 的内容复制到目标字符串 str1 中,确保复制操作安全进行(通过断言检查指针非空),并返回目标字符串的起始地址。

代码如下:

char* my_strcpy(char* des, const char* src)//防止src的内容被改变
{
	assert(des && src);    //防止des与src是空指针
	char* ret = des;       //作为返回值
	while (*des++ = *src++)//循环拷贝,当拷贝完'\0',判断为假,跳出循环
	{
		;                  //空循环体,执行赋值操作
	}
	return ret;
}
int main()
{
	char str1[40];
	char str2[40] = "abcdef";
	my_strcpy(str1, str2); //将arr2的内容拷贝进arr1
	printf("%s\n", str1);
	return 0;
}

strcat

1.strcat的用法

字符串连接函数实际上就是完成两个字符串相加的效果,即一个字符串连接在另一个字符串末尾,构成一个新的字符串。其函数原型如下:

char *strcat(char *dest, const char *src);

注意:

源字符串必须以'\0'结束

目标字符串中必须得有'\0',否则无法知道从哪里开始追加字符

目标空间必须足够大,确保能放下源字符串

目标空间必须可以修改

2.strcat的使用

int main()
{
	char str1[20] = "hello ";
	char str2[20] = "world";
	strcat(str1, str2);
	printf("%s\n", str1);
}

输出结果为:hello world

3.strcat的模拟实现

思路:strcat的模拟实现和strcpy的方法类似,都是替换,只是要让dest先指向末尾’\0’。

代码如下:

char* my_strcat(char* dest, const char* src) 
{
    assert(dest && src);
    //保存 dest 的原始地址,以便最后返回  
    char* ret = dest;
    //遍历 dest 字符串,直到找到其末尾的 '\0'  
    while (*dest) 
    {
        dest++;
    }

    //循环将 src 指向的字符串的字符逐个拷贝到 dest 的末尾  
    //当拷贝到 src 的结束符 '\0' 时,循环结束  
    //dest 和 src 都会自增,直到拷贝完成  
    while (*dest++ = *src++) 
    {
        //循环体为空,仅执行拷贝操作  
    }
    return ret;
}

int main()
{
    char str1[20] = "hello ";
    char str2[20] = "world";
    my_strcat(str1, str2);
    printf("%s\n", str1); 
    return 0;
}

strcmp

1.strcmp的用法

字符串比较函数,依照从左到右的顺序依次比较字符数组str1和字符数组str2对应位置字符的ASCII码值,并返回比较结果。

其函数原型为:

int strcmp(const char *s1, const char *s2);

注意:

s1为要比较的第一个字符串

s2为要比较的第二个字符串

字符串1=字符串2,返回0

字符串1>字符串2,返回大于0的数

字符串1<字符串2,返回小于0的数

2.strcmp的使用

int main()
{
	char str1[10] = "hello";
	char str2[10] = "world";
	int n = strcmp(str1, str2);
	if (n == 0)
		printf("str1=str2\n");
	if(n>0)
		printf("str1>str2\n");
	if(n<0)
		printf("str1<str2\n");
	return 0;
}

字符串的比较是从左到右依次比较字符的ASCII码值,'h'的ASCII码值比'w'的ASCII码值小,此时系统就不会再继续比较,而是直接输出结果

3.strcmp的模拟实现

思路:比较两个字符串是否相等,并返回它们的ASCII差值(如果不相等),同时确保输入的字符串指针不为空,并在比较过程中考虑了字符串结束符'\0'。

代码如下:

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	//使用while循环比较str1和str2指向的字符是否相等  
	while (*str1 == *str2)
	{
		// 如果当前字符是字符串结束符'\0',说明两个字符串到目前为止都相等  
		// 此时可以安全地返回0,表示两个字符串相等  
		if (*str1 == '\0')
		{
			return 0;
		}
		// 移动到字符串的下一个字符继续比较  
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

int main()  
{
	char str1[] = "abcd";
	char str2[] = "Abcd";
	int ret = my_strcmp(str1, str2);	
	printf("%d\n", ret);
	return 0;
}

strchr

1.strchr的用法

strchr函数,用于在一个字符串中查找给定字符的第一个匹配之处,并返回指向该字符的指针。如果没有找到该字符,则返回NULL。

其函数原型为:

char *strchr(const char *str, int c);

注意:

str为要查找的字符串,必须是一个以空字符‘\0’结尾的字符数组,即C语言中的字符串类型

c为要查找的字符,必须是一个整型值,通常是一个字符常量或变量

2.strchr的使用

int main()
{
	char str[20] = "hello world";
	char* ptr;
	ptr = strchr(str, 'w');
	if (ptr != NULL)
	{
		printf("找到了\n");
	}
	else
	{
		printf("找不到\n");
	}
}

3.strchr的模拟实现

思路:

先排查空指针,然后循环寻找,如果找到,直接返回其地址,找不到就返回空指针NULL

代码如下:

char* myStrchr(char* str, int c) 
{
    //使用while循环遍历字符串,直到遇到字符串结束符'\0'
    while (*str != '\0') 
    {
        if (*str == c) 
        {
            return str;
        }
        str++;
    }
    //如果遍历完整个字符串都没有找到字符c,返回NULL 
    return NULL;
}

int main() 
{
    char* str = "hello world";
    char* p = myStrchr(str, 'o');

    if (p != NULL) 
    {
        printf("找到了\n");
    }
    else 
    {
        printf("未找到\n");
    }

    return 0;
}

结束语

在这篇文章中,我们简单学习了一些字符函数和字符串函数,还有更多的字符串函数我将留在下一篇文章。

希望看到这篇文章的友友们,能点赞收藏加关注!!!

十分感谢!!!

上一篇:【 Vue 3】Vue3.0性能提升主要是通过哪几方面?


下一篇:国际化