【C语言】字符函数和字符串函数

各位读者好,小编现在来浅浅介绍一些C语言库函数中处理字符或字符串的函数。

目录

1.字符串函数

1.求字符串长度

1.strlen

2.长度不受限制的字符串函数

1.strcpy

2.strcat 

3.strcmp 

3.长度受限制的字符串函数

1.strncpy

2.strncat

3.strncmp 

4.字符串查找

1.strstr

2.strtok 

5.错误信息报告

1.strerror

2.字符函数 

1.字符分类函数

2.字符转换函数 

1.tolower 

2.toupper

3.ending:


注意:

1.C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。

2.字符串常量适用于那些对它不做修改的字符串函数。

3.以下代码的运行环境均处于32位(x86)系统且为小端机器下运行。

以下函数都可以在https://cplusplus.com/网站中查询到,好的,正文开始:

1.字符串函数

1.求字符串长度

1.strlen

网站查询如下:

strlen函数是一个获取字符串长度的函数,返回C字符串的长度。字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。函数的形参是一个被const修饰的 char*类型的指针变量str,该指针变量str指向所需计算长度的C字符串.

我们要注意以下几点:

1.使用strlen函数需要包含头文件<string.h>;

2.参数指向的字符串必须要以 '\0' 结束;

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

我们可以来看一个使用strlen函数的实例:

#include<stdio.h>
#include<string.h>
int main()
{
	char string[] = "abcd";
	size_t len = strlen(string);
	printf("%zu\n", len);
	return 0;
}

运行结果是4,这里就不展示了。结果是符合预期的!

对于注意事项的第4条,我们可以通过一个代码来方便大家理解,避免踩坑:

#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;
}

这里打印的是:"str2>str1"。这是为什么呢? 

其实也很简单,strlen函数计算str1字符串返回6,计算str2字符串返回3。但这两个返回值都是size_t类型(无符号数)的,这两个size_t类型的数值相减得到的仍然是size_t类型的数值 ,而size_t类型的取值范围应该是大于等于0的整数。所以这里并非数学思想中得到-3这个结果(-3的补码被当成无符号数将会是一个很大的数字:4,294,967,293)。

2.长度不受限制的字符串函数

1.strcpy

网站查询如下:

 strcpy函数是一个复制字符串的函数,将源字符串复制到目标数组中,复制包括源字符串的'\0'(并在'\0'处停止)。该函数所需形参分别是char*类型的指向目标空间的指针变量destination和被const修饰的char*类型的指向源字符串的指针变量source。返回值是一个char*类型的指向目标空间的指针变量。

我们要注意以下几点:

1.使用strcpy函数需要包含头文件<string.h>;

2.源字符串必须以 '\0' 结束;
3.会将源字符串中的 '\0' 拷贝到目标空间;
4.目标空间必须足够大,以确保能存放源字符串;
5.目标空间必须可变(目标空间不能为常量字符串);

6.源字符串和目标空间在内存中最好不要重叠,否则目标空间大小可能变化;

我们可以来看一个使用strcpy函数的实例: 

#include <stdio.h>
#include<string.h>
int main()
{
	
	char string1[20] = "hello woxxx";
	char* string2 = "rld";
	char* ret = strcpy(string1 + 8, string2);//将"rld"拷贝替换"xxx"
	printf("%s\n", ret);
	printf("%s\n", string1);
	return 0;
}

运行结果分别打印了"rld"和"hello world"。结果是符合预期的! 

2.strcat 

网站查询如下:

strcat函数是一个将源字符串追加到目标字符串的函数。从目标字符串的'\0'开始向后依次被源字符串的字符覆盖,两者串联形成新的字符串(将源字符串的'\0'也拷贝过去覆盖了,新字符串的末尾包含'\0')。该函数的形参和返回值与上strcpy函数一致,这里不在赘述。

我们要注意以下几点:

1.使用strcpy函数需要包含头文件<string.h>;

2.源字符串必须以 '\0' 结束;
3.目标空间必须有足够的大,能容纳下源字符串的内容;
4.目标空间必须可修改;

5.源字符串和目标空间在内存中不要重叠;

 我们可以来看一个使用strcat函数的实例: 

#include <stdio.h>
#include<string.h>
int main()
{
	
	char string1[20] = "XXX\0XXXXXXXXX";
	char string2[] = "abcd";
	char*ret=strcat(string1+1, string2);
	printf("%s\n", ret);
	printf("%s\n", string1);
	return 0;
}

运行结果分别打印了"XXabcd"和"XXXabcd"。我们可以分析以下:执行第三条语句时将字符数组string1第2个元素'X'的地址作为目标地址、将字符数组string2作为源字符串。但字符数组string1的第4个元素为'\0',那strcat函数就把这里当成了追加的开始位置,就从这里开始依次追加string2的5个元素(隐藏了'\0'),字符数组string1变成"XXXabcd\0XXXXX\0\0\0\0\0\0\0"。而strcat函数返回目标空间起始地址,即string1+1(指向字符数组string1第2个元素'X'),所以从这个地址开始打印(遇到'\0'停止打印)为"XXabcd"。而string1表示字符数组string1首元素的地址(指向字符数组string1第1个元素'X'),所以从这个地址开始打印(遇到'\0'停止打印)为"XXXabcd"。结果符合预期!

3.strcmp 

网站查询如下:

strcmp是一个比较两个字符串的函数。这个函数开始比较每个字符串的第一个字符,如果它们彼此相等,就继续比较每个字符串的下一个字符(即比较两个字符串对应位置上字符的ASCII值大小),直到字符不同或遇到'\0'为止。该函数的形参是两个被const修饰的char*类型的指针变量str1和str2,分别指向两个要比较的字符串。返回值是一个int类型的整数,该值指示字符串之间的关系。

返回值指示两个字符串之间的关系如下:

1.第一个字符串大于第二个字符串,则返回大于0的数字
2.第一个字符串等于第二个字符串,则返回0
3.第一个字符串小于第二个字符串,则返回小于0的数字

我们要注意以下几点:

 1.使用strcmp函数需要包含头文件<string.h>;

 我们可以来看一个使用strcmp函数的实例: 

#include <stdio.h>
#include<string.h>
int main()
{
	
	char string1[20] = "abcde";
	char string2[20] = "abcd";
	int ret=strcmp(string1, string2);//string1>string2
	printf("%d\n", ret);

	char arr1[20] = "abcd";
	char arr2[20] = "abcd";
	int com = strcmp(arr1, arr2);//arr1==arr2
	printf("%d\n", com);

	char str1[20] = "abc";
	char str2[20] = "abcd";
	int flag = strcmp(str1, str2);//str1<str2
	printf("%d\n", flag);

	return 0;
}

运行结果分别打印1、0、-1。 因为以上字符数组元素个数均为20,未初始化部分元素默认为'\0'(ascii码值为0),所以易知结果符合预期!

3.长度受限制的字符串函数

1.strncpy

网站查询如下:

 strncpy函数是一个复制字符串的函数。与strcpy函数功能大抵相同,但它规定了复制字符串的字符个数。strncpy函数有三个形参,第三个形参是一个size_t类型的整形num,表示所需复制字符串的字符个数;其他形参和返回值表示含义均与上strcpy函数一致。

我们要注意以下几点:

1.使用strcmp函数需要包含头文件<string.h>;

2.拷贝num个字符从源字符串到目标空间;
3.如果源字符串的长度不大于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个;
4.如果源字符串的长度大于num,则不会在目标的末尾追加'\0',即源字符串的'\0'不会拷贝进源字符串里;

5.目标空间必须可变(目标空间不能为常量字符串);

6.源字符串和目标空间在内存中不要重叠;

7.目标空间必须足够大,以确保能存放源字符串;

我们可以来看一个使用strncpy函数的实例:

#include <stdio.h>
#include<string.h>
int main()
{
	char string1[20] = "abcdef";
	char string2[20] = "xxx";
	char* ret = strncpy(string1, string2, 2);//源字符串长度大于num情况
	printf("%s\n",ret );
	printf("%s\n", string1);

	char str1[20] = "abcdef";
	char str2[] = "xxx";
	char* flag = strncpy(str1, str2, 4);//源字符串长度不大于num情况
	printf("%s\n", flag);
	printf("%s\n", str1);
	return 0;
}

运行结果如下:

结果契合strncpy函数的!

2.strncat

网站查询如下:

 strncat函数功能与strcat函数大抵相同,但它规定了从源字符串追加到目标空间的字符个数。strncat函数有三个形参,第三个形参是一个size_t类型的整形num,表示所需复制字符串的字符个数;其他形参和返回值表示含义均与上strcat函数一致。

我们要注意以下几点:

1.使用strcmp函数需要包含头文件<string.h>;

2.该函数追加完num个字符后,会额外追加一个'\0';

3.如果源字符串的长度小于num,则只复制源字符串'\0'之前的内容追加到目标空间,即多追加的部分无效;

5.目标空间必须有足够的大,能容纳下源字符串的内容;
6.目标空间必须可修改;

 我们可以来看一个使用strncpy函数的实例:

#include <stdio.h>
#include<string.h>
int main()
{
	char string1[20] = "hello wo";
	char string2[20] = "rld";
	char* ret = strncat(string1, string2, 3);
	printf("%s\n",ret );
	printf("%s\n", string1);

	char str1[20] = "hello b";
	char str2[] = "it";
	char* flag = strncat(str1, str2, 4);//源字符串长度小于num的情况
	printf("%s\n", flag);
	printf("%s\n", str1);
	return 0;
}

运行结果如下:

结果是符合预期的!

3.strncmp 

网站查询如下:

strncmp函数的功能也是大抵与strcmp函数相同,但是它规定了要比较的最大字符数。strncmp函数有三个形参,第三个形参是一个size_t类型的整形num,表示所需比较的最大字符个数;其他形参和返回值表示含义均与上strcmp函数一致。

我们要注意以下几点:

 1.使用strcmp函数需要包含头文件<string.h>;

 我们可以来看一个使用strcmp函数的实例:

#include <stdio.h>
#include<string.h>
int main()
{
	char string1[20] = "hello world";
	char string2[20] = "hello bit";
	int ret = strncmp(string1, string2, 11);
	printf("%d\n",ret );

	char str1[20] = "hello bicycle";
	char str2[] = "hello bike";
	int flag = strncmp(str1, str2, 7);//这里值比较前面7个相同字符
	printf("%d\n", flag);
	return 0;
}

结果分别打印1和0,符合预期的!

4.字符串查找

1.strstr

网站查询如下:

strstr函数是一个定位子串的函数。strstr函数有两个形参,第1个形参是一个被const修饰的char*类型的指针变量 str1,指向要扫描的字符串;第2个形参是一个被const修饰的char*类型的指针变量str2,指向要匹配的字符串(子串)。返回值是一个char*类型的指针变量,有3种情况:如果能在被扫描的字符串中(定位)找到子串,返回的指针变量指向被扫描字符串中子串第一次出现的位置;如果被扫描字符串中不存在这个子串,返回空指针;如果str2指向'\0',直接返回str1。

我们要注意以下几点:

 1.使用strcmp函数需要包含头文件<string.h>;

 我们可以来看一个使用strcmp函数的实例:

#include <stdio.h>
#include<string.h>
int main()
{
	char str[] = "This is a simple string";
	char* pch = strstr(str, "simple");//str中查找字符串"simple"
	if (pch != NULL)
	strncpy(pch, "sample", 6);//将"sample"复制目标空间pch(指向字符数组str第11个元素's')中
	puts(str);//输出复制更改后的str

	char string1[]="hello world";
	char string2[] = { 0 };
	char* ret = strstr(string1, string2);//string2指向'\0'的情况
	printf("%s\n", ret);

	char arr1[] = "hello bit";
	char arr2[] = "hello world";
	char* flag = strstr(arr1, arr2);//无法找到子串的情况
	printf("%p\n", flag);
	return 0;
}

运行结果如下:

结果是符合预期的!

2.strtok 

网站查询如下:

strtok函数是一个很特殊的函数,有两个形参:一个char*类型的指针变量str,指向一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记;一个被const修饰的char*类型的指针变量delimiters,指向一个字符串,定义了用作分隔符的字符集合。

如果有一个字符串:"2622077902@qq.com"。那么分隔符集合可以是字符串delimiters:"@.",标记可以是:"2622077902"、"qq"和"com"。没有规定这是唯一分法,分法主要取决于我们想要通过该函数实现什么。

而strtok函数的功能如下:

1.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
2.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
3.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
4.如果字符串中不存在更多的标记,则返回 NULL 指针。

我们要注意以下几点:

 1.使用strcmp函数需要包含头文件<string.h>;

2.strtok函数形参str指向的空间必须可修改;

我们用一个代码来理解该函数的功能:

#include <stdio.h>
#include<string.h>
int main()
{
	char str[] = "2622077902@qq.com";
	const char* delimiters = "@.";

	char* ret = strtok(str, delimiters);
	printf("%s\n", ret);//第一次打印

	ret = strtok(NULL, delimiters);
	printf("%s\n", ret);//第二次打印

	ret = strtok(NULL, delimiters);
	printf("%s\n", ret);//第三次打印


	ret = strtok(NULL, delimiters);
	printf("%s\n", ret);//第四次打印
	printf("%p\n", ret);//第五次打印

	printf("%s\n", str);//第六次打印

	return 0;
}

我们来看结果:

第一次执行strtok函数时, 第一个参数不为 NULL ,函数将找到str中第一个标记(2622077902),并将分隔符'@'修改成'\0',并保存标记在字符串中的位置,且返回一个指向这个标记的指针赋值给ret,打印的自然是2622077902;

第二次执行strtok函数时,第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记(qq),并将分隔符'.'修改成'\0',并保存标记在字符串中的位置,且返回一个指向这个标记的指针赋值给ret,打印的自然是qq;

第三次执行strtok函数时,第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记(com),这里没有更多分隔符可修改成'\0',而且com末尾本身就是'\0',所以不改分隔符。并保存标记在字符串中的位置,且返回一个指向这个标记的指针赋值给ret,打印的自然是com;

第四次执行strtok函数时,第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记,但字符串中不存在更多的标记,所以返回 NULL 指针,第四次和第五次打印自然为(null)和00000000。

第六次打印易知打印为2622077902,这里主要是想印证strtok函数会改变被操作的字符串(第一次执行strtok时分隔符'@'被修改成'\0'导致只能打印出2622077902)。

我们还可以根据strtok函数和for循环的特点优化上面代码:

#include <stdio.h>
#include<string.h>
int main()
{
	char str[] = "2622077902@qq.com";
	const char* delimiters = "@.";
	char* ret = NULL;
	for (ret = strtok(str, delimiters); ret != NULL; ret = strtok(NULL, delimiters))
	{
		printf("%s\n", ret);//前三次打印
	}
	ret = strtok(NULL, delimiters);
	printf("%s\n", ret);//第四次打印
	printf("%p\n", ret);//第五次打印
	printf("%s\n", str);//第六次打印
	return 0;
}

这里就不分析了,跟上面分析一致。

5.错误信息报告

1.strerror

网站查询如下:


 

strerror函数是将错误码翻译成错误信息,返回错误信息的字符串的起始地址。该函数的形参是一个int型的整形errnum。

C语言中使用库函数的时候,如果发生错误,就会将错误码放在一个全局变量errno里面。当我们使用库函数发生错误时,如不知道为什么发生错误,就可以将errno传参给strerror函数,在根据strerror返回的起始地址打印出错误信息。

我们要注意以下几点:

 1.使用strcmp函数需要包含头文件<string.h>;

我们可以来看一个使用strncpy函数的实例:

//打开文件的例子
/*fopen函数以读的形式打开文件。如果文件存在,打开成功;
如果文件不存在,打开失败,返回空指针。*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	FILE* pf = fopen("add.txt", "r");
	if (pf == NULL)
	{
		printf("打开文件失败,原因时:%s\n", strerror(errno));
	}
	else
	{
		printf("打开文件成功\n");
	}
	return 0;
}

在以上代码的当前文件夹中是没有"add.txt"文件的,看结果:


 

好的,结果符合预期!

2.字符函数 

1.字符分类函数

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

这些函数比较简单易懂,这里就不过多介绍了,有兴趣可以去网站查询哈!

2.字符转换函数 

1.tolower 

tolower函数是一个将大写字母转换成小写字母的函数。

2.toupper

toupper函数是一个将小写字母转换成大小字母的函数。

#include <stdio.h>
#include <ctype.h>//isupper函数和tolower函数所需头文件
int main()
{
	int i = 0;
	char str[] = "Test String.\n";
	char c;
	while (str[i])//循环遍历字符数组str
	{
		c = str[i];//字符数组str元素依次赋值给字符变量c
		if (isupper(c))//如字符变量c为大写字母
			c = tolower(c);//将大写字母转换成小写字母
		putchar(c);//输出字符变量c
		i++;
	}
	return 0;
}

 结果如下:

3.ending:

感谢阅读,跪求点赞。如有不足,恳请斧正!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

X_chengonly

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值