C语言——字符函数和字符串函数

耕耘 :C、C++、嵌入式技术领域

🔥我的个人主页

❄️个人专栏:《C语言专栏》 《嵌入式专栏》

✨**不要等待机会,而要创造机会!**✨

📽博主简介:

✨✨一位热爱生活的阳光大男孩.✨✨

前言

本文系统梳理了 C 语言标准库中常用的字符串处理函数,涵盖字符分类与转换、字符串长度计算、拷贝、连接、比较、查找、分割及错误处理等核心操作。每个函数均配有清晰的语法说明、功能解析、使用示例和关键注意事项,旨在帮助读者快速掌握这些基础但至关重要的工具,为编写高效、安全的 C 语言程序打下坚实基础。

1. 字符分类函数

C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h
在这里插入图片描述

下面就讲解一个函数,其他的用法也类似

int islower ( int c );

islower 是能够判断参数部分的 c 是否是⼩写字⺟的。通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回0。

#include <stdio.h>
#include <ctype.h>//islower的头文件
int main()
{
	int i = 0;
	char str[] = "Test String.\n";
	char c;
	while (str[i])
	{
		c = str[i];
		if (islower(c))//判断是否是小写,不是的话就返回1
		{
			c -= 32;     //修改成小写,修改ASCLL就可以了
		}
		putchar(c);    //函数,作用是打印单字符
		i++;
	}
	return 0;
}

介绍:putchar 是 C 语言标准库中的一个函数,用于向标准输出单个字符(每次调用仅输出一个字符)。其原型定义在头文件 <stdio.h>

2. 字符转换函数

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

int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写

上⾯的代码,我们将⼩写转⼤写,是-32完成的效果,有了转换函数,就可以直接使⽤ tolower 函数。

#include <stdio.h>
#include <ctype.h>
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;
}

3. strlen

3.1 代码演⽰

size_t strlen ( const char * str );

功能:统计参数 str 指向的字符串的⻓度。统计的是字符串中 ‘\0’ 之前的字符的个数。
参数:str :指针,指向了要统计⻓度的字符串。
返回值:返回了 str 指向的字符串的⻓度,返回的⻓度不会是负数,所以返回类型是 size_t

#include <stdio.h>
#include <string.h>
int main()
{
	const char* str = "abcdef";
	printf("%zd\n", strlen(str));//输出结果是6
	return 0;
}

使⽤注意事项:
1、字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数(不包含 ‘\0’ )。
2、参数指向的字符串必须要以 ‘\0’ 结束。
3、注意函数的返回值为 size_t ,是⽆符号的( 易错 )
4、strlen 的使⽤需要包含头⽂件 <string.h>

3.2 strlen返回值

#include <stdio.h>
#include <string.h>
int main()
{
	const char* str1 = "abcdef";
	const char* str2 = "bbb";
	if (strlen(str2) - strlen(str1) > 0)
	{
		printf("str2 > str1\n");
	}
	else
	{
		printf("srt1 > str2\n");
	}
	return 0;
}

3.3 strlen的模拟实现

方法1

//计数器⽅式
int my_strlen(const char* str)
{
	int count = 0;
	assert(str);
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

方法2:

//不能创建临时变量计数器
int my_strlen(const char* str)
{
	assert(str);
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

方法3:

//指针-指针的⽅式
int my_strlen(char* s)
{
	assert(str);
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}

4. strcpy

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

功能:字符串拷⻉,拷⻉到源头字符串中的 \0 为⽌。
参数:destination :指针,指向⽬的地空间
source :指针,指向源头数据
返回值:strcpy 函数返回的⽬标空间的起始地址

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[10] = { 0 };//他的空间要有固定值
	char arr2[] = "hello";
	strcpy(arr1, arr2);   //把arr2里面的字符拷贝进arr1
	printf("%s\n", arr1);
	return 0;
}

使⽤注意事项:
1、源字符串必须以 ‘\0’ 结束。
2、会将源字符串中的 ‘\0’ 拷⻉到⽬标空间。
3、⽬标空间必须⾜够⼤,以确保能存放源字符串。
4、⽬标空间必须可修改。

5. strcat

char * strcat ( char * destination, const char * source );

功能:字符串追加,把 source 指向的源字符串中的所有字符都追加到 destination 指向的空间中。
参数:destination :指针,指向⽬的地空间
source :指针,指向源头数据
返回值:strcat 函数返回的⽬标空间的起始地址

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello ";
	char arr2[] = "world";
	strcat(arr1, arr2);//把arr2里面的字符加到arr1中
	printf("%s\n", arr1);
	return 0;
}

使⽤注意事项:
1、源字符串必须以 ‘\0’ 结束。
2、⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
3、⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
4、⽬标空间必须可修改

6. strcmp

int strcmp ( const char * str1, const char * str2 );

功能:⽤来⽐较 str1 和 str2 指向的字符串,从两个字符串的第⼀个字符开始⽐较,如果两个字符的ASCII码值相等,就⽐较下⼀个字符。直到遇到不相等的两个字符,或者字符串结束。
参数:
str1 :指针,指向要⽐较的第⼀个字符串
str2 :指针,指向要⽐较的第⼆个字符串
返回值:
• 标准规定:
◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
◦ 第⼀个字符串等于第⼆个字符串,则返回0
◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abq";
	int ret = strcmp(arr1, arr2);
	printf("%d\n", ret);
	if (ret > 0)
		printf("arr1 > arr2\n");
	else if (ret == 0)
		printf("arr1 == arr2\n");
	else
		printf("arr1 < arr2\n");
	return 0;
}

7. strncpy(比strcpy多了一层保障)

char * strncpy ( char * destination, const char * source, size_t num )

功能:字符串拷⻉;将 source 指向的字符串拷⻉到 destination 指向的空间中,最多拷⻉ num个字符。
参数:
destination :指针,指向⽬的地空间
source :指针,指向源头数据
num :从source指向的字符串中最多拷⻉的字符个数
返回值:strncpy 函数返回的⽬标空间的起始地址

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "abcdefghi";
	char* str = strncpy(arr1, arr2, 5);//只拷贝arr2中的5个字母
	printf("%s\n", arr1);
	printf("%s\n", str);
	return 0;
}

7.2 ⽐较strcpy和strncpy函数

1、strcpy 函数拷⻉到 \0 为⽌,如果⽬标空间不够的话,容易出现越界⾏为。
2、strncpy 函数指定了拷⻉的⻓度,源字符串不⼀定要有 \0 ,同时在设计参数的时候,就会多⼀层思考:⽬标空间的⼤⼩是否够⽤, strncpy 相对 strcpy 函数更加安全

8. strncat

char * strncat ( char * destination, const char * source, size_t num );

功能:字符串追加;将 source 指向的字符串的内容,追加到 destination 指向的空间,最多追加 num 个字符。
参数:
destination :指针,指向了⽬标空间
source :指针,指向了源头数据
num :最多追加的字符的个数
返回值:返回的是⽬标空间的起始地址

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello ";
	char arr2[] = "world";
	char* str = strncat(arr1, arr2, 4);//只追加arr2中的4个字母
	printf("%s\n", arr1);
	printf("%s\n", str);
	return 0;
}

8.2 strcat和strncat对⽐

1、参数不同, strncat 多了⼀个参数
2、 strcat 函数在追加的时候要将源字符串的所有内容,包含 \0 都追加过去,但是 strncat 函数指定了追加的⻓度。
3、strncat 函数中源字符串中不⼀定要有 \0 了。
4、strncat 更加灵活,也更加安全。

9. strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

功能:字符串⽐较;⽐较 str1 和 str2 指向的两个字符串的内容,最多⽐较 num 字符。
参数:
str1 :指针,指向⼀个⽐较的字符串
str2 :指针,指向另外⼀个⽐较的字符串
num :最多⽐较的字符个数
返回值:
标准规定:
1、第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
2、第⼀个字符串等于第⼆个字符串,则返回0
3、第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcqw";
	int ret1 = strncmp(arr1, arr2, 3);//比较前三个字符,相等返回0
	printf("%d\n", ret1);
	int ret2 = strncmp(arr1, arr2, 4);//比较前四个字符,小于arr1的前四个,则返回一个小于0的数
	printf("%d\n", ret2);
	return 0;
}

9.2 strcmp和strncmp⽐较

1、参数不同
2、strncmp可以⽐较任意⻓度了
3、strncmp函数更加灵活,更加安全

10. strstr

char * strstr ( const char * str1, const char * str2);

功能:
strstr 函数,查找 str2 指向的字符串在 str1 指向的字符串中第⼀次出现的位置。
简⽽⾔之:在⼀个字符串中查找⼦字符串。
strstr 的使⽤得包含<string.h>
参数:
str1 :指针,指向了被查找的字符串
str2 :指针,指向了要查找的字符串
返回值:
1、如果str1指向的字符串中存在str2指向的字符串,那么返回第⼀次出现位置的指针
2、如果str1指向的字符串中不存在str2指向的字符串,那么返回NULL

#include <stdio.h>
#include <string.h>
int main()
{
	char str[] = "This is a simple string";
	char* pch;
	pch = strstr(str, "simple");//在str中找simple
	if (pch != NULL)
		printf("%s\n", pch);
	else
		printf("查找的字符串不存在\n");
	return 0;

11. strtok 函数的使⽤

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

功能
1、分割字符串:根据 delim 参数中指定的分隔符,将输⼊字符串 str 拆分成多个⼦字符串。
2、修改原始字符串: strtok 会直接在原始字符串中插⼊ ‘\0’ 终⽌符,替换分隔符的位置,因
此原始字符串会被修改。
参数
1、str :⾸次调⽤时传⼊待分割的字符串;后续调⽤传⼊ NULL ,表⽰继续分割同⼀个字符串。
2、 delim :包含所有可能分隔符的字符串(每个字符均视为独⽴的分隔符)。
返回值
1、成功时返回指向当前⼦字符串的指针。
2、没有更多⼦字符串时返回 NULL 。
使⽤步骤
1、⾸次调⽤:传⼊待分割字符串和分隔符。
2.、后续调⽤:传⼊ NULL 和相同的分隔符,继续分割。
3、 结束条件:当返回 NULL 时,表⽰分割完成。

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "192.168.6.111";   //这里的分隔符就是“.”
	const char* sep = ".";          //把分隔符放进sep中
	const char* str = NULL;
	char buf[30] = { 0 };
	strcpy(buf, arr); //将arr中的字符串拷⻉到buf中,对buf的内容进⾏切割
	for (str = strtok(buf, sep); str != NULL; str = strtok(NULL, sep))
	{
		printf("%s\n", str);       //找到一次打印一次
	}
	return 0;
}

11.2 注意事项

1、破坏性操作: strtok 会直接修改原始字符串,将其中的分隔符替换为 ‘\0’ 。如果需要保留原字符串,应先拷⻉⼀份。
2、连续分隔符:多个连续的分隔符会被视为单个分隔符,不会返回空字符串。
3、空指针处理:如果输⼊的 str 为 NULL 且没有前序调⽤,⾏为未定义。

12. strerror 函数的使⽤

char* strerror ( int errnum );

功能:
1、strerror 函数可以通过参数部分的 errnum 表⽰错误码,得到对应的错误信息,并且返回这个错误信息字符串⾸字符的地址。
2、strerror 函数只针对标准库中的函数发⽣错误后设置的错误码的转换。
3、strerror 的使⽤需要包含<string.h>
参数:
errnum :表⽰错误码
这个错误码⼀般传递的是 errno 这个变量的值,在C语⾔有⼀个全局的变量叫: errno ,当库函数的调⽤发⽣错误的时候,就会将本次错误的错误码存放在 errno 这个变量中,使⽤这个全局变量需要包含⼀个头⽂件 errno.h 。
返回值:
函数返回通过错误码得到的错误信息字符串的⾸字符的地址。

#include <errno.h>
#include <string.h>
#include <stdio.h>
//我们打印⼀下0~10这些错误码对应的信息
int main()
{
	int i = 0;
	for (i = 0; i <= 10; i++) {
		printf("%d: %s\n", i, strerror(i));
	}
	return 0;
}

//结果:
//0: No error
//1 : Operation not permitted
//2 : No such file or directory
//3 : No such process
//4 : Interrupted function call
//5 : Input / output error
//6 : No such device or address
//7 : Arg list too long
//8 : Exec format error
//9: Bad file descriptor
//10: No child processes
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	FILE* pFile = NULL;
	//fopen函数以读的形式打开⽂件,如果⽂件不存在,则打开失败。
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
	{
		printf("错误信息是:%s\n", strerror(errno));
		return 1;//错误返回
	}
	return 0;
}

//结果:
//错误信息是:No such file or directory

12.2 perror

void perror ( const char * str );

也可以了解⼀下 perror 函数, perror 函数相当于⼀次将上述代码中的第**“ printf(“错误信息是:%s\n”, strerror(errno)); ”**⾏完成了,直接将错误信息打印出来。 perror 函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	FILE* pFile = NULL;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
	{
		perror("错误信息是");//直接打印
		return 1;
	}
	return 0;
}

//结果:
//错误信息是: No such file or directory

结语

“关注我的都能暴富——别问,问就是玄学,反正我先信了!”
完.

                                                                                                                                                                                                                                                      完.
评论 47
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chen—LSN

赏金充咖啡,熬夜调试代码不打烊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值