首页 > 其他分享 >【字符函数以及字符串函数

【字符函数以及字符串函数

时间:2024-11-03 08:49:28浏览次数:5  
标签:p2 字符 p1 函数 int ret char 字符串

本章重点
重点介绍处理字符和字符串的库函数的使用和注意事项
求字符串长度
strlen
长度不受限制的字符串函数
strcpy
strcat
strcmp
长度受限制的字符串函数介绍
strncpy
strncat
strncmp
字符串查找
strstr
strtok

前言
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在
常量字符串 中或者 字符数组 中。
字符串常量 适用于那些对它不做修改的字符串函数

  1. 函数介绍
    1.1 strlen(求字符串长度的库函数)
    字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包
    含 ‘\0’ )。
    size_t strlen ( const char * str );
    参数指向的字符串必须要以 ‘\0’ 结束。
    注意函数的返回值为size_t,是无符号的( 易错 )
    学会strlen函数的模拟实现
int main()
{
	char ch[] = "hello world";
	size_t ret=strlen(ch);
	printf("%d\n", ret);
	return 0;
}

strlen的模拟实现
size_t strlen ( const char * str );我们按照他的格式模拟实现

//第一种普通的方法实现
int my_strlen(const char*p)
{
	int count = 0;
	while (*p != '\0')
	{
		p++;
		count++;
	}
	return count;
}
int main()
{
	char ch[] = "hello world";
	int ret=my_strlen(ch);
	printf("%d\n", ret);
	return 0;
}
//第二种是指针减指针的方法
int my_strlen(char* p)
{
	char* start = p;
	while (*start != '\0')
	{
		start++;
	}
	return start - p;
}
int main()
{
	char ch[] = "hello world";
	int ret=my_strlen(ch);
	printf("%d\n", ret);
	return 0;
}

第一种就是普通的方法,从首字符开始每移动一个字符,count+1,当遇到\0的时候就会跳出循环。
第二种就是利用指针-指针的方法(指针减指针绝对差值等于俩个元素之间的元素的个数)

2 strcpy(拷贝字符串函数的)
strcpy函数是一个用于拷贝字符串的函数,即将一个字符串中的内容拷贝到另一个字符串中(会覆盖原字符串内容)。它的参数是两个指针,第一个指向的是拷贝字符串的目的地的起始位置,即要将字符串拷贝到什么地方;第二个指向的是要拷贝字符串的内容的起始位置,即需要拷贝的字符串。它的返回值是目标空间的起始位置。
注意点:
源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
strlen的用法

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

strcpy的模拟实现

char* my_strcpy(char* p1, char* p2)
{
	char* ret = p1;
	while (*p1++ = *p2++)
	{
		;
	}
	return ret;
}
int main()
{
	char ch1[20] = { 0 };
	char ch2[] = "hello world";
	my_strcpy(ch1,ch2);
	printf("%s\n", ch1);
	return 0;
	}

```c

在这里插入图片描述
上面的图片中的内容应该是hello world\0我i写错了。

1.3 strcat(字符追加函数)
strcat函数是一个用于追加字符串的函数,即将一个字符串中的内容追加到另一个字符串后面(不会覆盖原字符串内容)。它的参数是两个指针,第一个指向的是追加字符串的目的地的起始位置,即要将字符串追加到什么地方;第二个指向的是要追加字符串的内容的起始位置,即需要追加的字符串。它的返回值是目标空间的起始位置。
char * strcat ( char * destination, const char * source );

int main()
{
	char ch1[20] = "abcde";
	strcat(ch1, "dfg");
	printf("%s\n", ch1);
	return 0;
}

在这里插入图片描述
strcat的模拟实现

char* my_strcat(char* p1, char* p2)
{
	char* ret = p1;
	while (*p1 != '\0')
	{
		p1++;
	}
	while (*p1++ = *p2++)
	{
		;
	}
	return ret;
}
int main()
{
	char ch1[20] = "abcde";
	my_strcat(ch1, "dfg");
	printf("%s\n", ch1);
	return 0;
}

在这里插入图片描述
首先经过第一个p1从a的地址经过while循环在遇到\0的时候跳出循环,来到如图中p1的位置,来到第二个循环,p把\0的位置覆盖掉,最后一直打印到\0停止循环。

1.4 strcmp(字符串比较函数)
int strcmp ( const char * str1, const char * str2 );
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
那么如何判断两个字符串?

int main()
{
	char ch1[] = "abcde";
	char ch2[] = "abq";
	int ret = strcmp(ch1, ch2);
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述
他是根据对应的字符进行比较的。如下图,c的ASLL值小于q的ASLL的值,返回-1.
在这里插入图片描述
strcmp的模拟实现

int my_strcmp(char* p1, char* p2)
{
	while (*p1++ == *p2++)
	{
		if (*p2 = '\0')
		{
			return  0;
		}
	}
	if (*p1 > *p2)
	{
		return 1;
	}
	else
		return -1;
}
int main()
{
	char ch1[] = "abcde";
	char ch2[] = "abq";
	int ret = my_strcmp(ch1, ch2);
	printf("%d\n", ret);
	return 0;
}

strcpy,strcat,strcmp这些都是长度不受限制的字符串函数,在遇到\0之前会不停的打印。
而长度受限制的如strncpy,strncat,strcmp这些是可以受控制的,用法也是非常相似的。
char * strncpy ( char * destination, const char * source, size_t num );
char * strncat ( char * destination, const char * source, size_t num );
int strncmp ( const char * str1, const char * str2, size_t num );
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这边就是他们的我写的一个简单的用法。

strstr(字符查找函数)
char * strstr ( const char *str1, const char * str2);
strstr函数可以在一个字符串(字符串1)中查找另一个字符串(字符串2),如果字符串2存在于该字符串1中,那么就返回被字符串2在字符串1中第一次出现的起始位置,如果在字符串1中找不到字符串2,那么就返回空指针(NULL)。它的第一个参数是字符串1的起始位置,第二个参数是字符串2的起始位置。
注意:

若字符串2为空字符串,则返回字符串1的起始位置。
举个例子,比如我们在字符串"abcdefbcd"中查找字符串"bcd"。

int main()
{
	char ch1[] = "abcdefbcd";
	char ch2[] = "bcd";
	char*ret=strstr(ch1, ch2);
	if (ret != NULL)
	{
		printf("%s\n",ret);
	}
	else
	{
		printf("找不到\n");
	}

	return 0;
}

在这里插入图片描述
他会找到b的地址,一直打印到\0结束。
注意:strstr函数的返回值是字符串"bcd"在字符串"abcdefbcd"中第一次出现的位置的起始位置,而不是出现几次就返回几个起始位置。

strstr的模拟实现
strstr模拟实现较为复杂。
2.模拟实现
strstr函数的模拟实现相对复杂,在实现过程中我们需要设置3个指针变量来辅助实现函数功能。
cp指针: 记录每次开始匹配时的起始位置,当从该位置开始匹配时就找到了目标字符串,便于返回目标字符串出现的起始位置;当从该位置开始没有匹配成功时,则从cp++处开始下一次的匹配。
p1和p2指针: 通过判断p1和p2指针解引用后是否相等来判断每个字符是否匹配成功,若成功,则指针后移比较下一对字符;若失败,p1指针返回cp指针处,p2指针返回待查找字符串的起始位置。

例如,在字符串"abbbcdef"中查找字符串"bbc":
刚刚开始时3个指针的指向如图所示
在这里插入图片描述
cp代表a的地址,p1现在也在a的位置上,p2在p的位置上。
p1!=p2,cp向右移动一个位置。
在这里插入图片描述
cp向右移动一个位置,使p1=cp,这时候p1=b,p2也等于b,p1继续移动,p1=b,
p2=b,p1=p2,继续移动,p1=b,p2=c,p1!=p2,移动cp的位置,变成如图中的位置
在这里插入图片描述
cp向右移动一个位置,然后p1=cp,p1=b,p2回到原始点,继续比较,一直到\0,p2就会停止。大体思路就是这样。

char* my_strstr(char* str1, char* str2)
{
	char* p1 = str1;
	char* p2 = str2;
	char* cp = str1;
	while (*cp)
	{
		p1 = cp;
		p2 = str2;
		while (*p1 == *p2)
		{
			p1++;
			p2++;
		}
		if (*p2 == '\0')
		{
			return cp;
		}
		cp++;
	}
	return NULL;
}
int main()
{
	char ch1[] = "abcdefbcd";
	char ch2[] = "bcd";
	char* ret = my_strstr(ch1, ch2);
	if (ret != NULL)
	{
		printf("%s\n", ret);
	}
	else
	{
		printf("找不到\n");
	}

	return 0;
}

最后一个就是 strtok(字符分割函数)
char * strtok ( char * str, const char * sep )
strtok函数能通过给定的一系列字符将一个字符串分割成许多子字符串的函数。它的第一个参数是需要被分割的字符串的首地址;第二个参数是一个字符串的首地址,该字符串是用作分隔符的字符集合。返回值是查找到的标记的首地址。
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
如果字符串中不存在更多的标记,则返回 NULL 指针。

int main()
{
	char ch[] = "[email protected]";
		char* p = "@.";
		char buffer[30] = { 0 };
		strcpy(buffer,ch);
		char*ret=strtok(buffer, p);
		printf("%s\n", ret);
		 ret = strtok(NULL, p);
		printf("%s\n", ret);
		ret = strtok(NULL, p);
		printf("%s\n", ret);
	return 0;
}

这样写太麻烦,可以换一种写法

int main()
{
	char ch[] = "[email protected]";
	char* p = "@.";
	char buffer[50] = { 0 };
	strcpy(buffer, ch);
	char* ret = NULL;
	for (ret = strtok(buffer, p); ret != NULL; ret = strtok(NULL, p))
	{
		printf("%s\n", ret);
	}
	return 0;
}

好了今天的内容大概就是这么多。

标签:p2,字符,p1,函数,int,ret,char,字符串
From: https://blog.csdn.net/2402_82552926/article/details/143453839

相关文章

  • 函数参数问题
    位置参数必选参数,必须按照位置次序,依次传入参数。defpower(x,n):s=1whilen>0:n-=1s=s*xreturns 默认参数给参数赋予值时,就是默认参数1、是必选参数在前,默认参数在后,否则Python的解释器会报错defpower(x,n=2):......
  • 记录一下自己的优化字符串匹配算法
    我愿称之KeBF算法Ke的BF(BruteForce,暴力检索)法关于其他字符串匹配算法示例源码#include<stdio.h>#include<string.h>intmain(){//读入两个字符串charms[100],ps[100];fgets(ms,sizeof(ms),stdin);fgets(ps,sizeof(ps),stdin);//......
  • 函数
    函数原型下列程序输入3个整数(3个数之和不会超过整型数的最大值),计算并输出它们的平均值。下划线填入那个(些)行既不会导致编译错误也不会导致编译警告。#include<stdio.h>____________________________________________________________A)函数原型直接省略B)getAver......
  • C和C++的字符串有什么不同?
    一、C语言中字符串的存储方式C语言没有专门用于存储字符串的变量类型,字符串都被存储在char类型的数组中,且以字符\0结尾;字符数组存储在C语言中,字符串常常以字符数组的形式进行存储。例如:charstr[]="Hello";这里定义了一个字符数组str,编译器会自动在字符串......
  • 代码随想录算法训练营第十天|leetcode232.用栈实现队列、leetcode225. 用队列实现栈、
    1leetcode232.用栈实现队列题目链接:232.用栈实现队列-力扣(LeetCode)文章链接:代码随想录视频链接:栈的基本操作!|LeetCode:232.用栈实现队列哔哩哔哩bilibili自己的思路:真的第一次接触这个概念,完全没有任何思路,甚至不知道从何下手1.1基本概念栈就是相当于砌墙的砖头,先......
  • 代码随想录算法训练营第九天|leetcode151.翻转字符串里的单词、卡码网55.右旋字符串、
    1leetcode151.翻转字符串里的单词题目链接:151.反转字符串中的单词-力扣(LeetCode)文章链接:代码随想录视频链接:字符串复杂操作拿捏了!|LeetCode:151.翻转字符串里的单词哔哩哔哩bilibili自己的思路:直接将空格去掉,然后分割字符串为列表,在列表中进行翻转,不在字符串内部操作......
  • C和C++的字符串有什么不同?
    C字符串C语言没有专门用于存储字符串的变量类型,字符串都被存储在char类型的数组中,且以字符 \0结尾;#include<stdio.h>intmain(){ charstr[4]="sv";//charstr[3]="sv";是错的 charstr[]="sv"; charstr[4]={'s','','v'......
  • List类函数使用讲解及模拟实现
    一.List介绍    1.List是一个支持在任意位置进行插入和删除的序列式容器。    2.List底层实现时使用的是双向链表结构,每个节点之间都互不相干,通过指针进行前后结点的指向。    3.List的优点在于进行数据的插入和删除的时候,不需要去大量的挪动数据,效......
  • 七、Go语言快速入门之函数func
    文章目录函数:one:GO语言函数介绍:two:函数的参数和返回值:star2:按值传递和按引用传递:star2:给返回值命名:star2:空白符:star2:改变外部变量:three:传递变长参数:four:`defer`和追踪:star2:`defer`使用:star2:`defer`实现代码追踪:five:递归函数:six:匿......
  • Python 函数综合案例
    设计格黑娜学院银行ATM定义一个全局变量:money,用来记录银行卡余额(默认5000000)定义一个全局变量:name,用来记录客户姓名(启动程序时输入)定义如下的函数:查询余额函数存款函数取款函数主菜单函数要求.程序启动后要求输入客户姓名.查询余额,存款,取款后都会返回主菜单.......