【C语言】字符函数+字符串函数详解

前言:

前段时间学习了字符函数和字符串函数,这里写篇文章总结一下~
——————————————————————
注意:每个函数都有相应的头文件,切记不可遗漏

一.求字符串长度的函数

1.strlen

(1)strlen函数介绍

在这里插入图片描述

strlen函数简单一句话就是求字符串长度的,注意是字符串,也可以是字符数组

总结为以下几点:

1.字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )
2.参数指向的字符串必须要以 ‘\0’ 结束
3.注意函数的返回值为size_t,是无符号的

strlen函数的使用

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

有以下代码:

int main()
{
    
    
	if (strlen("abc") - strlen("abcdef") > 0)
	{
    
    
		printf("大于\n");
	}
	else
	{
    
    
		printf("小于等于\n");
	}
	return 0;
}

strlen(“abc”)是3,strlen(“abcdef”)是6,3-6=-3,不满足条件,所以认为答案是小于等于,其实这是错误的。我们要注意:strlen函数的返回值是无符号的,3是无符号的数,6是无符号的数,两个数相减还是无符号的数,无符号的数没有负数只有整数,所以是大于。
如果要进行修改,把strlen强制转换成int 类型即可。

if ((int)strlen("abc") - (int)strlen("abcdef") > 0)

(2)strlen函数的模拟实现

第一种方式:
计数器

#include <string.h>
size_t my_strlen(char* str)
{
    
    
	int count = 0;
	while (*str != '\0')
	{
    
    
		count++;
		str++;
	}
	return count;
}
int main()
{
    
    
	char arr[] = "abcd";
	size_t len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

把字符数组传过去,str指向字符串的第一个元素,给个计数器,如果* str不为0,count加1,同时str地址加1,重复这样的过程,直到 * str等于0跳出循环,并且返回count 的值(count 的值就是字符串的长度)

第二种方式:
递归

int my_strlen(char* str)
{
    
    
	if (*str == '\0')
	{
    
    
		return 0;
	}
	else
	{
    
    
		return 1 + my_strlen(str + 1);
	}
}
int main()
{
    
    
	char arr[] = "abcd";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

如果*str=0,就直接返回0;如果不是,返回1加再次调用这个函数,字符串的地址往后移动,进入这个函数再判断,循环这个过程,直到遇到\0。

第三种方式:
指针-指针

int my_strlen(char* str)
{
    
    
	char* p = str;
	while (*p != '\0')
	{
    
    
		p++;
	}
	return p - str;
}
int main()
{
    
    
	char arr[] = "abcd";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

把str的地址赋给指针p,p指向的是字符串首元素的地址,解引用p如果不为斜杠0,地址+1,遇到斜杠0,返回此时p的地址减去字符串首元素的地址,就是字符串的长度。

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

1.strcpy

(1)strcpy函数介绍

在这里插入图片描述

strcpy的作用是拷贝字符串,把源头字符串拷贝到目标空间去
总结为以下几点:

源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。

strcpy函数的使用

#include <string.h> 
int main()
{
    
    
	char arr1[20] = {
    
     0 };
	char arr2[] = "abcdef";
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

验证是否拷贝了斜杠0:

	char arr1[20] = "ssssssssssss";

如果有斜杠0,则第7个” s “将被覆盖成斜杠0
在这里插入图片描述
还有一种情况,如果把字符串写成这样:

char arr2[7] = {
    
     'a','b','c','d','e','f','\0' };

在这末尾记住要加上斜杠0,否则运行错误

目标空间必须可变:

char* arr1 = "xxxxxxxxxxx";

此时arr1是常量字符串,不可改,所以这样写也不行。

(2)strcpy函数的模拟实现

char* my_strcpy(char* dest, const char* str)
{
    
    
	assert(dest != NULL);
	assert(str != NULL);
	char* a = dest;
	while (*dest++ = *str++)
	{
    
    
		;
	}
	return a;
}
int main()
{
    
    
	char arr1[20] = {
    
     0 };
	char arr2[] = "abcdef";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

将str的字符串拷贝给dest,所以str用const修饰,防止改变;用assert保证两个指针的有效性,防止为空指针;当str的值不为斜杠0时,把值赋给dest,同时两边地址++,当str是斜杠0时,把斜杠0拷贝给dest,此时dest为斜杠0跳出循环;在此之前,用一个字符指针变量先把dest保存起来,最后返回这个指针变量。

2.strcat

(1)strcat函数介绍

在这里插入图片描述
strcat函数的作用是把源头字符串接到目标空间后面

总结一下:

源字符串必须以 ‘\0’ 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。

strcat函数的使用:

int main()
{
    
    
	char arr1[20] = "hello";
	char arr2[] = "world";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

目标空间必须有斜杠0,这样才能知道从哪开始接加字符串(覆盖了目标空间的斜杠0);源字符串也必须有斜杠0,这样才知道把多少字符串的内容接到目标空间后面(包括源字符串的斜杠0),并且目标空间必须足够大。

(2)strcat函数的模拟实现

char* my_strcat(char* dest, char* str)
{
    
    
	assert(dest);
	assert(str);
	char* a = dest;
	while (*dest)
	{
    
    
		dest++;
	}
	while (*dest++ = *str++)
	{
    
    
		;
	}
	return a;
}
int main()
{
    
    
	char arr1[20] = "hello";
	char arr2[] = "world";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

将str的字符串拷贝给dest,所以str用const修饰,防止改变;用assert保证两个指针的有效性,防止为空指针;当解引用dest不为0,地址++,直到遇到斜杠0跳出循环;后面的跟strcpy函数的模拟实现相同。

字符串不可自己给自己加,否则会死循环。

3.strcmp

(1)strcmp函数介绍

在这里插入图片描述
strcmp函数作用是比较两个字符串,比较对应字符的大小

规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字

在这里插入图片描述
strcmp函数的使用:

int main()
{
    
    
	int len = strcmp("abc", "abb");
	printf("%d\n", len);//>0  
	int len1 = strcmp("abc", "abw");
	printf("%d\n", len1);//<0
	int len2 = strcmp("abc", "abc");
	printf("%d\n", len2);//=0
	return 0;
}

(2)strcmp函数的模拟实现

int my_strcmp(const char* str1, const char* str2)
{
    
    
	assert(str1 && str2);
	while (*str1 == *str2)
	{
    
    
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return (*str1 - *str2);
}
int main()
{
    
    
	int len = my_strcmp("abc", "abb");
	printf("%d\n", len);
	return 0;
}

返回的是整数,所以返回的类型是int 类型;两个字符串拿来作比较,所以用const防止被修改;用assert保证两个指针的有效性,防止为空指针;当两个字符串对应的字符相等时,两个地址同时++,只要有一个为斜杠0,两个字符串相等,返回0;如果不是,返回第一个字符串减去第二个字符串的数值。(返回3种情况:小于0,等于0,大于0,具体返回的值为多少不确定)

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

1.strncpy

在这里插入图片描述
strncpy函数的作用与strcpy函数类似,只是长度受限制
总结:

拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

strncpy函数的使用:

int main()
{
    
    
	char arr1[20] = "abcdef";
	char arr2[] = "xxxxxxxxx";
	strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

如果源字符串的个数小于要拷贝的个数,则补上\0。

2.strncat

在这里插入图片描述
strncat函数的作用与strcat函数类似,只是长度受限制

strncat函数的使用:

int main()
{
    
    
	char arr1[20] = "abcdef";
	char arr2[] = "xxxxxxxxx";
	strncat(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

arr1后面加5个x,同时还有\0。

3.strncmp

在这里插入图片描述
strncmp函数的作用与strcmp函数类似,只是长度受限制

strncmp函数的使用:

int main()
{
    
    
	char arr1[] = "abcdef";
	char arr2[] = "abcqty";
	int len = strncmp(arr1, arr2, 3);
	printf("%d\n", len);
	return 0;
}

只比较两个字符串的前3个字符,则相等;如果限制的个数是4,则小于0。

四.字符串查找函数

1.strstr

(1)strstr函数介绍

在这里插入图片描述
strstr函数的作用:找str2字符串中与str1有共同的字符串,相当于str2是str1的子集,找到了则在str1与str2相同的位置开始打印str1,没找到则返回空(null)

int main()
{
    
    
	char arr1[] = "abcdefghi";
	char arr2[] = "cde";
	char* len = strstr(arr1, arr2);
	printf("%s\n", len);
	return 0;
}

(2)strstr函数的模拟实现

char* my_strstr(char* str1, char* str2)
{
    
    
	char* cp = str1;
	char* s1 = cp;
	char* s2 = str2;
	if (*str2 == '\0')
	{
    
    
		return str1;
	}
	while (*cp)
	{
    
    
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
    
    
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return cp;
		cp++;
	}
	return NULL;
}
int main()
{
    
    
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";
	char* len = my_strstr(arr1, arr2);
	if (len != NULL)
	{
    
    
		printf("%s\n", len);
	}
	else
		printf("找不到\n");
	return 0;
}

cp:从这个位置开始打印的参数;
s1、s2:两个用来匹配两个字符串是否有相同子字符串的参数;
cp、s1从str1的首字符开始,s2从str2的首字符开始,在匹配之前先判断str2是否为空,如果是,则返回str1(直接打印arr1)。cp是开始打印的起始位置,如果它遍历完(遇到斜杠0,则返回空,找不到),如果不为斜杠0,进入第一层循环,把此时的cp的位置赋给s1,s2再刷新到str2的首字符位置,进入第二层循环,如果s1不为0,s2,不为0,并且两个相等,则s1和s2的地址++;如果s1与s2不相等了,跳出第二层循环,cp地址++,然后再进入第一层循环,把地址+1后的cp赋给s1,s2又刷新到str2首字符的位置,重复上面的过程,如果s1为0,则返回空,找不到;如果s2为0,说明已经找到了,返回cp的地址,然后开始打印的位置就从cp的地址开始打印str1。

2.strtok

char * strtok ( char * str, const char * sep )

总结以下几点:

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

strtok函数的使用:

int main()
{
    
    
	char arr[] = "abcd#efg.hi@789";
	char copy[30];
	strcpy(copy, arr);
	char sep[] = "#.@";
	char* len = NULL;
	for (len = strtok(copy, sep); len != NULL; len = strtok(NULL, sep))
	{
    
    
		printf("%s\n", len);
	}
	return 0;
}

五.错误信息报告函数

1.strerror

在这里插入图片描述
strerror函数的作用是返回错误码,所对应的错误信息。
库函数在执行的时候,如果发生了错误,会将一个错误码存放在errno这个变量中,errno是全局变量。

#include <errno.h>
int main()
{
    
    
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d: %s\n", i, strerror(i));
	}
	return 0;
}

打印出0~9的错误信息:
在这里插入图片描述

六.字符分类函数

函数 如果他的参数符合下列条件就返回真
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 任何可打印字符,包括图形字符和空白字符

七.字符转换函数

int tolower ( int c );

功能:把大写字母字符转换成小写,非大写字母字符不做处理,头文件是<ctype.h>

int toupper ( int c );

功能:把小写字母转换成大写,非小写字母字符不做处理,头文件是<ctype.h>

在这里插入图片描述
感谢大家的观看 ~ ~ ~ ~ ~

猜你喜欢

转载自blog.csdn.net/2301_77459845/article/details/131806803
今日推荐