C语言—详解库函数中常用的字符串函数

news2024/11/19 23:38:59

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在
常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数。本篇文章为大家详解八个常用的字符串操作函数,同时我们尝试模拟实现该函数,加深我们对函数的认识和了解。 

目录

1. strlen 

1.1 strlen()函数简介 

1.2 strlen()的基本使用 

1.3 模拟实现strlen()函数 

2. strcpy 

2.1 strcpy()函数简介 

2.2 strcpy()的基本使用 

2.3 模拟实现strcpy()函数 

 3. strcat

3.1 strcat()函数简介 

3.2 strcat()的基本使用 

3.3 模拟实现strcat()函数 

4. strcmp 

4.1 strcmp()函数简介 

4.2 strcmp()的基本使用 

4.3 模拟实现strcmp()函数 

5. strncpy 

5.1 strncpy()函数简介 

 5.2 strncpy的基本使用

5.3 模拟实现strncpy()函数 

6.  strncat

6.1 strncat() 函数简介

6.2  strncat的基本使用 

6.3 模拟实现strncat()函数 

 7. strncmp

7.1 strncmp()函数简介

7.2 strncmp的基本使用 

7.3 模拟实现strncmp()函数 

8. strstr

8.1 strstr()函数简介 

8.2 strstr的基本使用 

8.3 模拟实现strstr()函数

1. strlen

1.1 strlen()函数简介 

strlen(): 返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。

函数原型

 注:

需包含<string.h>头文件

字符串以 '\0' 作为结束标志。
参数指向的字符串必须要以 '\0' 结束
注意函数的返回值为size_t,是无符号的(unsigned int)( 易错 )

1.2 strlen()的基本使用 

int main()
{
	const char* p = "Hello world";
	int len = (int)strlen(p);
	printf("%d\n", len);
	return 0;
}

1.3 模拟实现strlen()函数 

 创建临时变量

#include <stdio.h>
#include <assert.h>
// 创建临时变量实现strlen
int my_strlen(const char* str)
{
	int count = 0;
	assert(str);//不为空指针
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

int main()
{
	const char* ch = "abcdef";
	int len = my_strlen(ch);
	printf("%d\n", len);// 6 
	return 0;
}

不创建临时变量(递归实现)

// 不创建临时变量实现strlen
int my_strlen(const char* str)
{
	if (*str == '\0')
	{
		return 0;
	}
	else
	{
		return 1 + my_strlen(str + 1);
	}
}

int main()
{
	const char* ch = "abcdef";
	int len = my_strlen(ch);
	printf("%d\n", len);// 6 
	return 0;
}

2. strcpy 

2.1 strcpy()函数简介 

strcpy(): 将源指向的C字符串复制到目标指向的数组中,包括终止空字符(并在该点停止)

 函数原型

 注:Destination(目的地),Source(源自)

需包含<string.h>头文件

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

2.2 strcpy()的基本使用 

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

2.3 模拟实现strcpy()函数 

#include <stdio.h>
#include <assert.h>
//模拟实现strcpy函数
char* my_strcpy(char* des, const char* sou)
{
	char* ret = des;
	assert(des && sou);//不为空指针
	// 拷贝
	while (*des++ = *sou++)
	{
		;
	}
	return ret;//返回目标地址
}

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

 3. strcat

3.1 strcat()函数简介 

strcat(): 将源字符串的副本追加到目标字符串。目标中的终止空字符(\0)被源的第一个字符覆盖,并在目标中两者的连接形成的新字符串的末尾包含一个空字符(\0)。

函数原型

 注:

需包含<string.h>头文件

源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改
不可自己追加追加

3.2 strcat()的基本使用 

int main()
{
	char ch1[30] = "hello ";
	const char ch2[] = "world";
	strcat(ch1, ch2);
	printf("%s\n", ch1);
	return 0;
}

3.3 模拟实现strcat()函数 

#include <stdio.h>
#include <assert.h>
//模拟实现strcat
char* my_strcat(char* des, const char* sou)
{
	assert(des && sou);
	char* ret = des;
	//找到目标字符串的‘\0’
	while (*des)
	{
		des++;
	}
	//追加
	while (*des++ = *sou++)
	{
		;
	}
	return ret;//返回目标地址
}
int main()
{
	char ch1[30] = "hello ";
	const char ch2[] = "world";
	my_strcat(ch1, ch2);
	printf("%s\n", ch1);// hello world
	return 0;
}

4. strcmp 

4.1 strcmp()函数简介 

strcmp(): 比较每个字符串的第一个字符。如果它们相等,则继续执行以下对,直到字符不同或到达一个终止的空字符为止。 

函数原型

返回值:

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

比较大小的依据:不是比较两个字符串的长度,而是比较两个字符串中字符的ASCII码值大小

4.2 strcmp()的基本使用 

int main()
{
	const char* p1 = "abcdef";// a 的ASCII码为 97
	const char* p2 = "bcdef";//  b 的ASCII码为 98
	int ret = strcmp(p1, p2);
	printf("%d\n", ret);
	return 0;
}

4.3 模拟实现strcmp()函数 

#include <stdio.h>
#include <assert.h>
// 模拟实现strcmp
int my_strcmp(const char* des, const char* sou)
{
	assert(des && sou);
	//如果两个字符相等,继续往后面找到不同字符进行比较
	while (*des == *sou)
	{
		//元素全部相等
		if (*des == '\0')
		{
			return 0;
		}
		des++;
		sou++;
	}
	//返回值
	return *des - *sou;
}

int main()
{
	const char* p1 = "abcdef";// a 的ASCII码为 97
	const char* p2 = "bcdef";//  b 的ASCII码为 98
	int ret = my_strcmp(p1, p2);
	printf("%d\n", ret);
	return 0;
}

5. strncpy 

5.1 strncpy()函数简介 

strncpy():将源字符串的num个字符复制到目标。如果源字符串的结束在复制字符之前找到,目标将用0填充,直到总共向其写入了num字符 。

函数原型

注:

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

 5.2 strncpy的基本使用

int main()
{
	char p1[20] = "abcd";
	const char p2[] = "hello";
	strncpy(p1, p2,2 );
	printf("%s\n", p1);
	return 0;
}

5.3 模拟实现strncpy()函数 

#include <stdio.h>
#include <assert.h>
// 模拟实现strncpy
char* my_strncpy(char* des, const char* sou, unsigned int num)
{
	assert(des && sou);
	char* ret = des;
	//拷贝
	while (num && (*des++ = *sou++))//num范围
	{
		num--;
	}
	//范围大于源字符串全部置0
	if (num)
	{
		while (--num)//先--再使用,避免多进入循环一次
		{
			*des++ = '\0';
		}
	}
	return des;//返回目标值
}
int main()
{
	char p1[20] = "abcd\0aaaaaaa";
	const char p2[] = "hello";
	my_strncpy(p1, p2, 8);
	printf("%s\n", p1);
	return 0;
}

6.  strncat

6.1 strncat() 函数简介

strncat(): 将源字符串的num个字符加上一个结束空字符追加到目标。如果源字符串中的追加字符串的长度小于num,则只复制终止空字符之前的内容。 

函数原型

 注:

需包含<string.h>头文件

如果源字符串中的追加字符串的长度小于num,则只复制终止空字符之前的内容

6.2  strncat的基本使用 

int main()
{
	char p1[20] = "hello";
	const char p2[] = "world";
	strncat(p1, p2, 3);
	printf("%s\n", p1);
	return 0;
}

6.3 模拟实现strncat()函数 

#include <stdio.h>
#include <assert.h>
// 模拟实现strncat
char* my_strncat(char* des, const char* sou, unsigned int num)
{
	assert(des && sou);//不为空
	char* ret = des;
	//找到目标字符串的'\0'
	while (*des)
	{
		des++;
	}
	//按给定范围追加
	while (num && (*des = *sou))
	{
		num--;
		des++;
		sou++;
	}
	return ret;//返回目标地址
}

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

 7. strncmp

7.1 strncmp()函数简介

 strncmp(): 比较到出现一个字符串结束或者num个字符全部比较完

函数原型

返回值

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

注:

比较是两个字符串一起比较相同num范围

比较的是两个字符串中字符的ASCII码值大小

7.2 strncmp的基本使用 

int main()
{
	const char* p1 = "abcdef";
	const char* p2 = "bcde";
	int ret = strncmp(p1, p2, 2);//比较的是ab-bc
	printf("%d\n", ret);
	return 0;
}

7.3 模拟实现strncmp()函数 

#include <stdio.h>
#include <assert.h>
int my_strncmp(const char* p1, const char* p2, unsigned int num)
{
	assert(p1 && p2);//不为空
	//先找到不相同的字符
	while (num && (*p1 == *p2))
	{
		num--;
		p1++;
		p2++;
	}
	if (num == 0)//num个字符都相等
		return 0;
	else
		return *p1 - *p2;
}
int main()
{
	const char* p1 = "dbcdef";
	const char* p2 = "dzde";
	int ret = my_strncmp(p1, p2, 2);//比较的是db-dz
	printf("%d\n", ret);// -24 
	return 0;
}

8. strstr

8.1 strstr()函数简介 

strstr(): 查找子字符串,返回指向目标字符串中需要查找到的第一个出现的指针,如果str2不是str1的一部分,则返回一个空指针 

函数原型

 注:

如果源字符串中出现多个需查找的子字符串,返回的是第一个出现的地址

8.2 strstr的基本使用 

int main()
{
	const char* p1 = "abcdefg";
	const char* p2 = "cd";
	char* ret = strstr(p1, p2);
	printf("%s\n", ret);
	return 0;
}

8.3 模拟实现strstr()函数

#include <stdio.h>
#include <assert.h>
//模拟实现strstr
char* my_strstr(const char* p1, const char* p2)
{
	assert(p1 && p2);//不为空
	char* s1 = NULL;
	char* s2 = NULL;//使p1和p2发生改变
	char* cur = (char*)p1;//用来存放查找到地址
	if (*p2 == '\0')//查找子字符串只存放了'\0'
	{
		return (char*)p1;
	}
	//开始查找
	while (*cur)
	{
		s1 = cur;
		s2 = (char*)p2;
		//查找到一个相同的字符串,判断后面是不是全部相同,两个字符串不为\0,s1等于s2
		while (*s1 && *s2 && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		// 判断s1被查完既查找字符串长度大于源字符串abc-abcd
		if (*s1 == '\0')
		{
			return NULL;
		}
		//判断p2是否全部查找完了
		if (*s2 == '\0')
		{
			return cur;//返回第一次出现的地址
		}
		cur++;
	}
	return NULL;//源字符串查找完了没找到子字符串中的内容,返回空指针
}

int main()
{
	const char* p1 = "abcdefg";
	const char* p2 = "cd";
	char* ret = my_strstr(p1, p2);
	printf("%s\n", ret);// cdefg
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/62600.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenCV入门(C++/Python)-使用OpenCV裁剪图像(四)

裁剪是为了从图像中删除所有不需要的物体或区域。甚至突出显示图像的特定功能。 使用OpenCV裁剪没有特定的功能&#xff0c;NumPy数组切片是工作。读取的每个图像都存储在2D数组中&#xff08;对于每个颜色通道&#xff09;。只需指定要裁剪区域的高度和宽度&#xff08;以像素…

Linux安装 dotnet sdk 6.0

一、离线安装&#xff08;推荐&#xff09; 1、下载安装包 官网下载地址 2、安装 &#xff08;1&#xff09;将安装包上传到linux服务器上的指定目录&#xff0c;如&#xff1a;/root/dotnet/sdk&#xff0c;运行下面指令解压即可 # cd /root/dotnet/sdk # mkdir -p $HOM…

毕设项目 - SSM留学生交流互动论坛系统(含源码+论文)

文章目录1 项目简介2 实现效果2.1 界面展示3 设计方案3.1 概述3.2 系统流程3.2.1 系统开发流程3.2.2 学生登录流程3.2.3 系统操作流程3.3 系统结构设计4 项目获取1 项目简介 Hi&#xff0c;各位同学好呀&#xff0c;这里是M学姐&#xff01; 今天向大家分享一个今年(2022)最新…

微服务的好处(优点)有哪些?

显然&#xff0c;随着系统复杂度的提升&#xff0c;以及对系统扩展性的要求越来越高&#xff0c;微服务化是一个很好的方向&#xff0c;但除此之外&#xff0c;微服务还会给我们带来哪些好处&#xff1f; 独立&#xff0c;独立&#xff0c;还是独立 我们说微服务打响的是各自…

虹科方案|具有RDMA复制写入日志的高可用性HDD存储集群可提供出色的性能

一、引言 Open-E、Western Digital 和 ATTO 数据存储专家和工程师联手推出了基于 HDD 的数据存储设备&#xff0c;该设备结合Western Digital Ultrastar Data60 JBOD 的海量容量和Ultrastar 系列 HDD 以及加速的性能&#xff0c;这得益于ATTO HBA SAS 控制器和 100GbE NIC&…

制作一个简单HTML大学生抗疫感动专题网页(HTML+CSS)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

一文刨析C/C++全局常量的定义

目录 文件特性常量 文件常量 堆常量 EOF, WEOF errno 常量 数学常量 数学错误常量 共享常量 转换模式常量 文件读/写访问常量 NULL (CRT) stdin, stdout, stderr 文件特性常量 语法 #include <io.h> 备注 这些常量指定由函数指定的文件或目录的当前特性。…

软件杂志软件杂志社软件编辑部2022年第9期目录

基金项目论文 基于Blockly和树莓派的多模态控制智能车 杨杰;宋俊炜;吴思玮;魏苏州;赖晓晨; 1-313 基于神经网络的网络异常研究与实现 郭稼逸; 4-6《软件》投稿&#xff1a;cnqikantg126.com 计算机视觉技术在电力系统自动化中的应用 陈海远;顾雅青; 7-9 基于优…

【吴恩达机器学习笔记】十二、降维

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为学习吴恩达机器学习视频的同学提供的随堂笔记。 &#x1f4da;专栏简介&#xff1a;在这个专栏&#xff0c;我将整理吴恩达机器学习视频的所有内容的笔记&…

PM说 | 一文全方位解析C端用户的评论功能!

随着各种自媒体、资讯平台的肆意发展&#xff0c;评论区逐渐成为各路英雄豪杰的必争之地。在评论区&#xff0c;我们可以与”“杠精”来一场遭遇战&#xff0c;邂逅文人墨客&#xff0c;看一场舌战群雄大戏。 评论区越热闹&#xff0c;说明产品越活跃&#xff0c;用户粘性高&a…

iwebsec靶场 文件上传漏洞通关笔记1-第01关 前端js过滤绕过

目录 第01关 前端js过滤绕过 1.禁用js法 &#xff08;1&#xff09;禁用js &#xff08;2&#xff09;刷新页面使生效 &#xff08;3&#xff09;上传脚本 &#xff08;4&#xff09;开启js并刷新页面 2.修改页面法1 &#xff08;1&#xff09;右键查询元素 &#xff…

docker安装和info信息

docker 容器的历史&#xff1a; 1、Chroot Jail 就是我们常见的 chroot 命令的用法。它在 1979 年的时候就出现了&#xff0c;被认为是最早的容器化技术之一。 它可以把一个进程的文件系统隔离起来。 2、The FreeBSD Jail Freebsd Jail 实现了操作系统级别的虚拟化&#…

csapp 读书笔记

第二章&#xff1a;信息的表示和处理 历史上因程序bug导致重大事故的情况很多是由数字溢出&#xff0c;缓冲区溢出导致的。 本章主要讲的是基本数据类型的(IEEE)表示&#xff0c;大小端&#xff0c;以及二进制位运算的骚操作案例。 第三章&#xff1a;程序的机器级表示 本章…

名窑讲坛:钧瓷“神、奇、妙、绝”四大特色之“妙”——纹路

文/倾灵叶 钧瓷以“入窑一色&#xff0c;出窑万彩”的神奇窑变著称于世。 钧瓷的纹路是经自然窑变形成的具有自身典型艺术特征釉面装饰&#xff0c;是特殊的釉料和独特的烧成工艺的产物&#xff0c;与其他窑系陶瓷作品人工雕刻、压刻和绘制而成的纹饰存在着本质的不同&#xf…

12家硬件厂商发布飞桨生态发行版 软硬一体协同发展

11月30日&#xff0c;由深度学习技术及应用国家工程研究中心主办、百度飞桨承办的WAVE SUMMIT2022深度学习开发者峰会如期举行。峰会上&#xff0c;百度AI技术生态总经理马艳军发布了飞桨深度学习平台的最新技术和生态进展&#xff0c;全新发布飞桨开源框架2.4版本&#xff0c;…

Fast Report .NET 2023.1 Crack

Fast Report .NET 适用于 .NET 6、.NET Core、Blazor、ASP.NET、MVC 和 Windows 窗体的全功能报告库。它可以在 Microsoft Visual Studio 2022 和 JetBrains Rider 中使用。 适用于 .NET 6、.NET Core、Blazor、ASP.NET、MVC 和 Windows 窗体的全功能报告库。它可以在 Microso…

计算机毕业论文java毕业设计选题源代码ssm的校园单车自行车租赁系统|租车系统

&#x1f496;&#x1f496;更多项目资源&#xff0c;最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 3.2.1技术可行性&#xff1a;技术背景 系统的开发环境和配置都是可以自行安装的&#xff0c;使用比较成熟的开发工具和数据库进行对系统用户…

Highlight_Matching_Pair问题解决

Highlight_Matching_Pair问题解决1 <SNR>20_Highlight_Matching_Pair1.1 提示的问题1.2 出发问题出现的条件1.2.1 访问到“&#xff08;&#xff09;”时会出现1.2.1 访问到不成对的“{}”时会出现2 解决办法2.1 首先确认matchparen.vim是否最新2.2 将vim更新到最新的版本…

数据结构—查找方法改进流程

文章目录哈希表哈希表 >红黑树—1—> 哈希表缺点—2—> 二维数组—3—> 数组加链表—4—> 树—5—> 有序二叉树—6—> 平衡二叉树—7—> 多叉树—8—> 红黑树红黑树的特点红黑树和链表的选择———————————————————————————…

ansible的主机清单和Playbook(剧本)

一、inventory---主机清单 1.1 支持对主机分组&#xff0c;每个组内可以定义多个主机&#xff0c;可以把一台主机分别放在两个组内。 把.10到.100的主机全部放在这个组里面&#xff08;/etc/ansible/hosts:配置文件&#xff09; 有的主机不是以ip地址放在主机清单里的&#x…