首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >字符函数和字符串函数

字符函数和字符串函数

作者头像
用户11831438
发布2025-12-30 13:28:35
发布2025-12-30 13:28:35
1980
举报
1.字符分类函数

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

我们介绍其中的一个函数,其余函数类似:

代码语言:javascript
复制
int islower ( int c );

islower是 可以判断参数部分的c是否是小写字母,如果是小写字母,则返回非0的整数,如果不是小写字母,则返回0;

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

代码语言:javascript
复制
#include<stdio.h>
#include<ctype.h>
int main()
{
	char arr[] = "hello BIT";
	int i = 0;
	while (arr[i])
	{
		if (islower(arr[i]))
		{
			arr[i] -= 32;
		}
		i++;
	}
	printf("%s\n", arr);
	return 0;
}
2.字符转换函数

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

代码语言:javascript
复制
int tolower ( int c) ;//将参数传进去的大写字母转成小写字母

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

学习了上面的字符转换函数,我们就可以改写上面的练习代码:

代码语言:javascript
复制
#include<stdio.h>
#include<ctype.h>
int main()
{
	char arr[] = "hello BIT";
	int i = 0;
	while (arr[i])
	{
		if (islower(arr[i]))
		{
			arr[i]=toupper(arr[i]);
		}
		i++;
	}
	printf("%s\n", arr);
	return 0;
}
3.strlen函数的使用和模拟实现
代码语言:javascript
复制
//函数原型
size_t strlen ( const char* str );

功能:统计参数str指向的字符串的长度,统计的是字符串中\0之前的字符个数。

参数: str :指针,指向了要统计长度的字符串(一般传字符的首地址返回值:返回了str指向的字符串的长度,返回的长度不可能是负数,所以返回类型是size_t。

代码演示:

代码语言:javascript
复制
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "hello bit";
	printf("%zu\n", strlen(arr));
    //%zu是打印无符号类型的整数
	return 0;
}

模拟实现:

代码语言:javascript
复制
//方式一 创建第三变量
size_t my_strlen(const char* str)
{
	const char* strat = str;
	while (*str)
	{
		str++;
	}
	return str - strat;
}
int main()
{
	char arr[] = "hello bit";
	size_t ret = my_strlen(arr);
	printf("%zu\n", ret);
	return 0;
}

//方式二 不创建其余变量
size_t my_strlen(const char* str)
{
	if (*str=='\0')
	{
		return 0;
	}
	else
	{
		return 1 + my_strlen(str + 1);
	}
}
int main()
{
	char arr[] = "hello bit";
	size_t ret = my_strlen(arr);
	printf("%zu\n", ret);
	return 0;
}

使用注意事项: 字符串必须以‘\0’作为结束标志,strlen函数返回的是在字符串中的'\0'之前的字符个数(不包含\0). 参数指向的字符串必须以'\0'结束。 注意函数的返回类型是size_t类型,是无符号类型。 strlen函数在使用的时候需要包含头文件string.h。

练习题:

代码语言:javascript
复制
#include<string.h>
int main()
{
	if (strlen("abc") - strlen("abcdef") > 0)
	{
		printf(">\n");
	}
	else
	{
		printf("<\n");
	}
	return 0;
}

strlen("abc")的结果是3,strlen("abcdef")的结果是6,很明显3-6<0,那strlen("abc") - strlen("abcdef")的结果就是小于0的吗?我么通过编译器运行可以发现最终打印出的是 >,这是什么原因呢?

我们知道strlen函数的返回类型是size_t类型,也就是无符号整型,计算机在进行运算的时候,是对二进制的补码进行加减运算,size_t类型它认为内存中存的(补码)就是无符号整型,32位二进制全是有效位,所以最终结果是大于0的。

4.strcpy函数的使用和模拟实现
代码语言:javascript
复制
//函数原型
char* strcpy(char* destination ,const char* source);

功能:字符串拷贝,将源头数据拷贝到目标空间,直到遇见源头数据中的 '\0'时停止拷贝。

参数: destination : 指针,指向目的地空间; source:指针,指向源头数据。 返回值: strcpy函数返回目标空间的起始地址(注意:可以是destination,也可以用变量来接收这个返回值)

代码演示:

代码语言:javascript
复制
//strcpy
int main()
{
	char src[] = "hello bit";
	char dest[20] = { 0 };
	strcpy(dest, src);
	printf("%s\n", dest);
	return 0;
}

模拟实现:

代码语言:javascript
复制
//模拟实现
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
	assert(src);
	while (*dest++ = *src++)//1.*dest=*str  2.dest++,str++  3.判断循环条件
	{
		;
	}
	return dest;
}
int main()
{
	char src[] = "hello bit";
	char dest[20] = { 0 };
	my_strcpy(dest, src);
	printf("%s\n", dest);
	return 0;
}

while (*dest++ = *src++) { ; } 这段代码的意思是:1.执行赋值语句*dest=*src 2. dest++ src++ 3.条件判断 赋值表达式的结果是被复制的值(即赋值的字符),看赋值表达式的结果是否为0。*dest++ = *src++后置++,现使用再++。

使用注意事项: 源字符串必须以 ‘\0’结束; 会将源字符串中的‘\0’拷贝到目标空间; 目标空间必须足够大,以保证能存放原字符串,并且必须是可以修改的 ; 遇见‘\0’停止拷贝,‘\0’后面的数据不拷贝。

5.strcat函数的使用和模拟实现
代码语言:javascript
复制
//函数原型
char* strcat(char* destination , const char* source);

功能:字符串追加,将source指向的源头字符串中的所有字符串都追加到destination指向的空间里。从目标空间中的‘\0’位置开始追加,追加到源头数据的‘\0’停止追加(如果源头数据中存在多个‘\0’则遇到最靠前的停止追加),并且将源头数据中的‘\0’也追加到目的地。

参数: destination : 指针。指向目的地空间; source : 指针,指向源头数据。 返回值: strcat函数返回的是目标空间的起始地址。(该返回值可以是destination,也可以用变量来接收返回值)

代码演示:

代码语言:javascript
复制
//strcat
int main()
{
	char dest[20] = "hello";
	char str[] = "world";
	//方式一
	//strcat(dest, str);
	//printf("%s\n", dest);
	//方式二
	char* ret= strcat(dest, str);
	printf("%s\n", ret);
	return 0;
}

模拟实现:

代码语言:javascript
复制
#include<assert.h>
char* my_strcat(char* dest, const char* str)
{
	assert(dest && str);
	char* ret = dest;
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *str++)
	{
		;
	}
	return ret;
}
int main()
{
	char dest[20] = "hello";
	char str[] = "world";
	char* ret = my_strcat(dest, str);
	printf("%s\n", ret);
	return 0;
}

使用注意事项: 源字符串必须以‘\0’结束; 目标字符串中也必须要有‘\0’,否则没办法直到从哪里开始追加; 目标空间必须足够大,能容下源字符串的内容; 目标空间必须是可修改的。

6.strcmp函数的使用和模拟实现
代码语言:javascript
复制
//函数原型
int strcmp(const char* str1, const char* str2);

功能 :用来比较str1和str2指向的字符串,从两个字符串的第一个字符开始比较,如果两个字符的ASCII码值相等,就比较下一个字符。直到遇见不相等的两个字符,或者是字符串结束。

参数: str1: 指针,指向的是要比较的第一个字符串; str2: 指针,指向的是要比较的第二个字符串。 返回值: 如果第一个字符串大于第二个字符串,则返回大于0的数字; 如果第一个字符串小于第二个字符串,则返回小于0的数字; 如果第一个字符串等于第二个字符串,则返回0。

代码演示:

代码语言:javascript
复制
int main()
{
	char arr1[] = "extravgant";
	char arr2[] = "arrogant";
	int ret=strcmp(arr1, arr2);
	if (ret > 0)
	{
		printf(">\n");
	}
	else if (ret == 0)
		printf("==\n");
	else
		printf("<\n");
	return 0;
}

模拟实现:

代码语言:javascript
复制
//模拟实现
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while(*str1 == *str2)
	{
		if (*str1)
		{
			return 0;
		}
		str1++;
		str2++;
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	else
		return -1;
}
int main()
{
	char arr1[] = "extravgant";
	char arr2[] = "arrogant";
	int ret = my_strcmp(arr1, arr2);
	if (ret > 0)
	{
		printf(">\n");
	}
	else if (ret == 0)
		printf("==\n");
	else
		printf("<\n");
	return 0;
}
7.strcnpy函数的使用和模拟实现
代码语言:javascript
复制
//函数原型
char* strncpy(char* destination, const char* source,size_t num);

功能:字符串拷贝,将source指向的字符串拷贝到destination指向的空间中,最多拷贝num个字符。

参数: destination : 指针,指向目的地空间; source :指针,指向源头数据; num : 从source指向的字符串中最多拷贝的字符个数。 返回值: strncpy函数返回目标空间的起始地址。(可以是destination,也可以用其他变量来接收这个返回值)

代码演示:

代码语言:javascript
复制
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "world you";
	strncpy(arr1, arr2, 5 * sizeof(char));
	printf("%s\n", arr1);
	return 0;
}

模拟实现:

代码语言:javascript
复制
#include<assert.h>
char* my_strncpy(char* dest, const char* str, size_t num)
{
	assert(str);
	while (num--)
	{
		*dest = *str;
		dest++;
		str++;
	}
	return dest;
}
int main()
{
	char arr[10] = { 0 };
	char arr2[] = "hello bit";
	my_strncpy(arr, arr2, 5);
	printf("%s\n", arr);
	return 0;
}

注意事项: 若源头数据中的字符数不足num个,则主动用‘\0’补够num个,若拷贝不够num个,但提前遇到‘\0’,则停止拷贝,不够的用'\0'补齐。 strncpy函数指定了拷贝的长度,源字符串不一定要有'\0'。

8.strcnat函数的使用和模拟实现
代码语言:javascript
复制
//函数原型
char* strncat(char* destination, const char* source,size_t num);

功能:字符串追加,将source指向的字符串的内容,追加到destination指向的空间,最多追加num个字符,追加完成后自动添加'\0',若源头字符串中的字符个数不足num个,则有几个就追加几个。

参数: destination : 指针,指向目的地空间; source :指针,指向源头数据; num : 从source指向的字符串中最多追加的字符个数。 返回值: strncat函数返回目标空间的起始地址。(可以是destination,也可以用其他变量来接收这个返回值)

代码演示:

代码语言:javascript
复制
//strncat 在末尾追加字符串,限定字符个数
#include<string.h>
int main()
{
	char str[] = "how are you";
	char dest[30] = "good morning";
	strncat(dest, str, 3);
	printf("%s\n", dest);
	return 0;
}

模拟实现:

代码语言:javascript
复制
#include<assert.h>
char* my_strncat(char* dest, const char* str, size_t num)
{
	assert(str);
	char* ret = dest;
	while (*dest)
		dest++;
	while (num--)
	{
		*dest = *str;
		dest++;
		str++;
	}
	return ret;
}
int main()
{
	char str[] = "how are you";
	char dest[30] = "good morning";
	my_strncat(dest, str, 3);
	printf("%s\n", dest);
	return 0;
}
9.strncmp函数的使用
代码语言:javascript
复制
//函数原型
int strncmp(const char* str1,const char* str2,size_t num);

功能:字符串的比较,比较str1和str2指向的两个字符串的内容,最多比较num个字符。

参数: str1 : 指针,指向一个比较的字符串; str2 :指针,指向一个比较的字符串; num :最多比较的字符个数。 返回值: 如果第一个字符串大于第二个字符串,则返回大于0的数字; 如果第一个字符串小于第二个字符串,则返回小于0的数字; 如果第一个字符串等于第二个字符串,则返回0。

代码演示:

代码语言:javascript
复制
//strncmp 比较限定前num个字符
#include<string.h>
int main()
{
	char arr1[] = "abcdcvknf";
	char arr2[] = "abc";
	int ret=strncmp(arr1, arr2, 4);
	if (ret > 0)
		printf(">");
	else if (ret < 0)
		printf("<");
	else
		printf("=");
	return 0;
}
10.strstr的函数使用和模拟实现
代码语言:javascript
复制
//函数原型
char* strstr(const char* str1, const char* str2);

功能:查找str2指向的字符串在str1指向的字符串中第一次出现的位置。简而言之:在一个字符串中查找子字符串。

参数: str1 :指针,指向了被查找的字符串; str2 :指针,指向了要查找的字符串。 返回值: 如果找到了,则返回第一次在str1中出现的起始地址;如果没找到,就返回NULL。

代码演示:

代码语言:javascript
复制
#include<string.h>
int main()
{
	char str1[] = "abbcdfe";
	char str2[] = "bbc";
	char* ret=strstr(str1, str2);
	printf("%s\n", ret);
	return 0;
}

模拟实现:

代码语言:javascript
复制
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	const char* p = str1;//p为可能匹配成功的起始位置
	const char* s1 = NULL;;
	const char* s2 = NULL;
	if (*str2 == '\0')
		return str1;
	while (*p)//寻找次数,*p不等于str1中的'\0',就说明还有可能找到
	{
		s1 = p;
		s2 = str2;
		//找一次的匹配过程
        //while(*s1 == *s2 && *s2!='\0' && *s1!='\0')
		while (*s1 == *s2 && *s2 && *s1)//当两个字符串都没有到达\0,才进行查找
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return (char*)p;
		p++;
	}
	return NULL;
}
int main()
{
	char str1[] = "bbc";
	char str2[] = "abbcdfe";
	char* ret = my_strstr(str1, str2);
	if (ret == NULL)
		printf("找不到\n");
	else
		printf("找到了,%s\n", ret);
	return 0;
}
11.strtok函数的使用
代码语言:javascript
复制
//函数原型
cahr* strtok(char* str,const cahr* delim);

功能: 分割字符串:根据delim参数中指定的分隔符,将输入字符串str拆分成多个子字符串。 修改原始字符串:strtok会直接在原始字符串中插入‘\0’终止符,替换分隔符的位置,因此原始字符串会被修改。

参数: str:首次调用时传入待分割的字符串;后续调用传入NULL,表示继续分割同一个字符串。 delim :包含所有可能分隔符的字符串(每个字符均视为独立的分隔符)。 返回值: 成功时返回指向当前子字符串的指针,若没有更多子字符串时返回NULL。

使用步骤: 1.首次调用:传入待分割字符串和分隔符。 2.后续调用:传入NULL和相同的分隔符,继续分割。 3.结束条件:当返回NULL时,表示分割完成。

代码演示:

代码语言:javascript
复制
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[] = "3604400378@qq.com";
	char str2[] = "@.";
	char str3[30] = { 0 };
	strcpy(str3, str1);
	char* ret = NULL;
	for (ret = strtok(str3, str2); ret != NULL;ret=strtok(NULL,str2))
	{
		printf("%s\n", ret);
	}
	return 0;
}

注意事项: 破坏性操作:strtok会直接修改原始字符串,将其中的分隔符替换成‘\0’。如果需要保留原始字符串,应先拷贝一份。 连续分隔符:多个连续的分隔符会被视为单个分隔符,不会返回空字符串。 空指针处理:如果输入的str为NULL且没有前序调用,行为未定义。

12.strerror函数的使用
代码语言:javascript
复制
//函数原型
char* strerror(int errnum);

功能: 1. strerror 函数可以通过参数部分的 个错误信息字符串⾸字符的地址。 2. errnum 表示错误码,得到对应的错误信息,并且返回这 strerror 函数只针对标准库中的函数发⽣错误后设置的错误码的转换。 3. strerror 的使⽤需要包含<string.h>

参数:

errnum: 表示错误码

这个错误码一般传递的是errno这个变量的值,在C语言中有一个全局变量叫:errno ,当库函数的调用发生错误的时候,就会将本次错误的错误码存放在errno这个变量中,使用这个全局变量需要包含一个头文件errno.h。

返回值:

函数返回通过错误码得到的错误信息字符串的首字符的地址。

代码演示:

代码语言:javascript
复制
#include<string.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	return 0;
}

strerror函数是将错误码翻译成错误信息,然后通过printf函数将错误信息打印出来,不知道有没有小伙伴感到有一点麻烦?有没有一种函数可以自己找到错误信息,然后自己打印出来呢?当然是有的。

12.1 perror

perror函数可以直接将错误信息打印出来。perror函数打印完参数部分的字符串后,再打印一个冒号和空格,再打印错误信息。

代码演示:

代码语言:javascript
复制
#include<string.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	return 0;
}

输出:

完结~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.字符分类函数
  • 2.字符转换函数
  • 3.strlen函数的使用和模拟实现
  • 4.strcpy函数的使用和模拟实现
  • 5.strcat函数的使用和模拟实现
  • 6.strcmp函数的使用和模拟实现
  • 7.strcnpy函数的使用和模拟实现
  • 8.strcnat函数的使用和模拟实现
  • 9.strncmp函数的使用
  • 10.strstr的函数使用和模拟实现
  • 11.strtok函数的使用
  • 12.strerror函数的使用
    • 12.1 perror
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档