【C语言】常见的字符串函数

©作者:末央&

©系列:C语言初阶(适合小白入门)
©说明:以凡人之笔墨,书写未来之大梦

在这里插入图片描述

目录

  • strlen函数
    • 模拟实现
  • strstr子串查找函数
    • 模拟实现
  • strtok字符串分割

strlen函数

strlen函数是一个用于求字符串长度的库函数。它的参数是被求长度的字符串的起始地址,返回值是一个无符号整型。

注意:

1.参数指向的字符串要以’\0’结束。
2.trlen返回的是在字符串中’\0’之前出现的字符个数(不包含’\0’)。
3.注意函数的返回值为size_t,是无符号的(易错)。

模拟实现

方式一:计数器的方式
我们定义一个变量为count,如果传入的指针指向的内容不是’\0’,那么count++,同时指针后移一位,循环往复,直到找到’\0’时返回count即可。

size_t my_strlen1(const char* str)
{
	size_t count = 0;//计数器
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

方式二:递归的方式
我们一进入函数体就判断传入指针指向的内容是否为’\0’,如果是就返回0,不是就返回1+my_strlen2(str+1),如此进行下去,直到递归到内层时找到’\0’,这时再一步步将值返回回来即可。

size_t my_strlen2(const char* str)
{
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen2(str + 1);
}

方式三:指针-指针的方式
进入函数体时,我们事先定义一个指针变量将传入的指针保存下来,然后将传入的指针向后移,直到遇到’\0’时,我们返回当前指针与保存的指针的差值即可。(指针与指针的差的绝对值是两个指针之间的元素个数)

size_t my_strlen3(const char* str)
{
	const char* p = str;//保存起始位置
	while (*str != '\0')
		str++;
	return str - p;
}

strstr子串查找函数

char *strstr( const char *string, const char *strCharSet );

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

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

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcdefbcd";
	char arr2[] = "bcd";
	char* ret = strstr(arr1, arr2);//在arr1中查找arr2字符串第一次出现的位置
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到\n");
	return 0;
}

注意:strstr函数的返回值是字符串"bcd"在字符串"abcdefbcd"中第一次出现的位置的起始位置,而不是出现几次就返回几个起始位置。

模拟实现

这里讲一下下面代码中各个指针的作用。

  • cur指针,主要记录每次主串开始匹配的位置,为了防止子串和主串第一次没有匹配成功,而方便多次匹配。如果这次没匹配成功,则cur++开始从下一个位置匹配。

  • -p1和sp指针: 通过判断s1和s2指针解引用后是否相等来判断每个字符是否匹配成功,若成功,则指针后移比较下一对字符;若失败,p1指针返回cp指针处,p2指针返回待查找字符串的起始位置

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	if (*str2 == '\0')		//空串
	{
		return str1;
	}
	const char* cur = str1;
	const char* p2 = str2;		//不改变字符加const
	const char* p1 = str1;
	while (*cur)
	{
		p1 = cur;
		p2 = str2;
		while (*p1 == *p2 && *p1 && *p2)		//这里判断p1是为了判断下一个字符是否为\0,节省循环次数
		{
			p1++;
			p2++;
		}
		if (*p2 == '\0')
		{
			return cur;
		}
		cur++;
	}
	return NULL;//不是子串
	
}
int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";
	char* ret = my_strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf("%s不是字串\n",arr2);
	}
	else
	{
		printf("%s\n", ret);
	}
	return 0;
}

在这里插入图片描述

strtok字符串分割

char *strtok( char *strToken, const char *strDelimit );

  • strtok函数能通过给定的一系列字符将一个字符串分割成许多子字符串的函数。它的第一个参数是需要被分割的字符串的首地址;第二个参数是一个字符串的首地址,该字符串是用作分隔符的字符集合。返回值是查找到的标记的首地址。

  • 注意:

    strtok函数找到strToken中的一个标记时,会将其用 \0结尾并返回这个标记的首地址。

  • strtok函数会改变strToken函数,所以在使用strtok函数切分的字符串都是临时拷贝的内容并且可修改。

  • strtok函数的第一个参数不为NULL时,函数将找到strToken中的第一个标记,并保存它在字符串中的位置。

  • strtok函数的第一个参数为NULL时,函数将从同一个字符串中被保存的位置开始查找它的下一个标记。

  • 若字符串中不存在更多的标记,则返回NULL指针。

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "2957055542@qq.com";//待分割字符串
	char arr2[] = "@.";//分隔符的字符集合
	char arr3[20] = { 0 };
	strcpy(arr3, arr1);//将数据拷贝一份使用,防止原数据被修改
	char* token = strtok(arr3, arr2);//第一次传参需传入待分割字符串首地址
	while (token != NULL)//说明还未分割完
	{
		printf("%s\n", token);
		token = strtok(NULL, arr2);//对同一个字符串进行分割,第二次及以后的第一个参数为NULL
	}
	return 0;
}

注意:当strtok函数找到第一个标记时,将其后的’@‘字符改为’\0’并返回第一个标记的首地址,所以我们以返回的地址为首地址开始打印字符串的时候就只会打印出2957055542,第二次再对该字符串调用strtok函数时将从’@'字符后面开始寻找下一个标记。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

免费分享:2000-2021年全国分省250mNDVI数据集(附下载方法)

NDVI (Normalized Difference Vegetation Index)归一化植被指数&#xff0c;又称标准化植被指数。是目前应用最广泛的植被指数&#xff0c;与植被的分布呈线性相关&#xff0c;是植被生长状态和空间分布的最佳指示因子&#xff0c;也是遥感估算植被覆盖度(FVC&#xff0c;Fract…

VMware Workstation 安装 Centos 虚拟机

1. 下载 VMware Workstation 直接上网找官网下载即可 2. 下载 Centos 镜像 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 3.打开 VMware 创建虚拟机 3.1点击创建虚拟机 3.2 选择自定义安装 3.3 选择使用 Workstation 的版本 版本越高兼容性越低但性能越好&#xff0c;一…

APP性能测试

1、性能测试分类&#xff1a;&#xff08;CPU&#xff0c;内存&#xff0c;流量&#xff0c;时间&#xff08;启动耗时计算&#xff09;&#xff0c;电量&#xff0c;流畅度&#xff08;帧率&#xff09;&#xff09;&#xff0c;稳定性&#xff08;崩溃&#xff0c;闪退&#…

[数据库原理]数据库设计(er图)

xtu期末是机试&#xff0c;所以图形表示有点不同 实体之间的关系&#xff1a; 多对多&#xff1a;可以生成一个新的关系模型一对一&#xff1a;两边都要关联一对多、多对一 &#xff1a;一的主键可以作为多的外键 如有错误&#xff0c;欢迎指正&#xff01;&#xff01;&#x…

年轻人「入侵」厂货电商:泼天的富贵or甜蜜的烦恼?

【潮汐商业评论/原创】 “明天我们带个黑色塑料袋&#xff0c;假装是批发拿货的&#xff0c;看看能不能淘到好货。这个批发‘黑话’你也学一下&#xff0c;别到时候露馅。” Paula正兴冲冲地跟Grace计划去服装批发市场“消费”。 只不过&#xff0c;与以往普通进店客人身份不…

瀚高数据库2024最新版_6.0.4_Windows版安装使用---国产瀚高数据库工作笔记007

首先去下载安装包: 下载的是企业版,可以试用一年 首先安装的时候,直接,下一步下一步就可以了 注意要用administrator去安装. 下载以后一步步去安装就可以了 ,桌面上会出现 但是连接不上,并且, 如果从管理工具中,找到服务 cmd services.msc 打开以后,找到瀚高服务,但是…

C# 验证PDF数字签名的有效性

数字签名作为PDF文档中的重要安全机制&#xff0c;不仅能够验证文件的来源&#xff0c;还能确保文件内容在传输过程中未被篡改。然而&#xff0c;如何正确验证PDF文件的数字签名&#xff0c;是确保文件完整性和可信度的关键。本文将详细介绍如何使用免费.NET控件通过C#验证PDF签…

【机器学习】机器学习的重要方法——线性回归算法深度探索与未来展望

欢迎来到 破晓的历程博客 引言 在数据科学日益重要的今天&#xff0c;线性回归算法以其简单、直观和强大的预测能力&#xff0c;成为了众多领域中的基础工具。本文将详细介绍线性回归的基本概念、核心算法&#xff0c;并通过五个具体的使用示例来展示其应用&#xff0c;同时探…

深入STM32的ADC世界:从理论到实践,打造精准数据采集系统

摘要: 在嵌入式系统中&#xff0c;模拟信号的采集与处理至关重要。本文将深入浅出地介绍STM32的ADC模块&#xff0c;结合实际项目&#xff0c;详细阐述ADC的工作原理、配置方法以及数据处理技巧&#xff0c;并辅以Mermaid图表和代码示例&#xff0c;助你轻松掌握ADC应用开发。 …

最小步数模型——AcWing 1107. 魔板

最小步数模型 定义 最小步数模型通常是指在某种约束条件下&#xff0c;寻找从初始状态到目标状态所需的最少操作或移动次数的问题。这类问题广泛存在于算法、图论、动态规划、组合优化等领域。具体来说&#xff0c;它涉及确定一个序列或路径&#xff0c;使得按照特定规则执行…

智能数字人直播带货软件源码系统 实现真人直播形象 带完整当然安装代码包以及搭建教程

系统概述 智能数字人直播带货软件源码系统&#xff0c;是一个集成了先进的人工智能、3D建模、语音合成、自然语言处理等技术于一体的创新平台。它旨在通过构建高度定制化的虚拟主播&#xff0c;为用户提供沉浸式、高效能的直播体验。与传统直播相比&#xff0c;该系统的核心优…

基于自回归超先验的有损图像压缩框架

文章信息 论文题目为《Joint Autoregressive and Hierarchical Priors for Learned Image Compression》&#xff0c;文章来自NIPS2018谷歌团队,是第一篇端到端图像压缩论文《variational image compression with a scale hyperprior》的改进版本&#xff0c;在《variational i…

Java 并发集合:CopyOnWrite 写时复制集合介绍

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 016 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

【Qwen2部署实战】Qwen2初体验:用Transformers打造智能聊天机器人

系列篇章&#x1f4a5; No.文章1【Qwen部署实战】探索Qwen-7B-Chat&#xff1a;阿里云大型语言模型的对话实践2【Qwen2部署实战】Qwen2初体验&#xff1a;用Transformers打造智能聊天机器人3【Qwen2部署实战】探索Qwen2-7B&#xff1a;通过FastApi框架实现API的部署与调用4【Q…

IIC电平转换电路原理

一、电平转换的必要性 在IIC主从设备连接时&#xff0c;由于主从设备可能存在不同的电源电压&#xff08;如5V、3.3V、1.8V等&#xff09;&#xff0c;导致需要进行电平转换以确保正常通信。 二、电平转换电路的基本组成 电平转换电路通常包括上拉电阻、MOS管&#xff08;通常…

C++基础(二):C++入门(一)

C是在C的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许多有用的库&#xff0c;以及编程范式 等。熟悉C语言之后&#xff0c;对C学习有一定的帮助&#xff0c;本篇博客主要目标&#xff1a; 1. 补充C语言语法的不足&#xff0c;以及C是如何对C语言设计…

AI与音乐:终极对决,机械混音师将扬弃人类知识!

AI与音乐 一. 引言1.1 AI在音乐创作中的应用1.2 AI在音乐表演与演奏中的应用 二. AI在音乐创作中的应用2.1 AI在音乐创作中的应用技术2.1.1 深度学习2.1.2 遗传算法2.1.3 神经网络 2.2 不同AI算法在音乐创作中的应用2.2.1 使用LSTM神经网络模型生成新的音乐2.2.2 使用基于模板的…

`THREE.LineBasicMaterial` 是 three.js 中用来创建用于绘制线条的基本材质。

demo案例 THREE.LineBasicMaterial 是 three.js 中用来创建用于绘制线条的基本材质。以下是它的入参、出参、方法和属性的详细说明。 入参 (Constructor Parameters) THREE.LineBasicMaterial 构造函数可以接收一个包含多个属性的对象。常用属性如下&#xff1a; const ma…

c++ 构造,析构,拷贝,移动构造函数

文章目录 概述1.构造函数2. 拷贝构造函数3.移动构造函数4.析构函数 例子QTUE4/5 c 小结 概述 对于c来说&#xff0c;最基础的是类。对于一个类来说&#xff0c;主要由以下函数构成。如下&#xff1a; 构造函数拷贝构造函数移动构造函数析构函数 当然&#xff0c;还有一个操作…

做测试/爬虫 selenium 元素定位 谷歌浏览器 插件推荐,提高元素定位效率

注:插件均在谷歌应用商店 下载 1.XPath Helper 插件 作用&#xff1a;用于Html中对目标字段或者属性值进行匹配 快捷启动&#xff1a;ctrl shift x 示例图如下&#xff1a; 2. ChroPath 插件 作用&#xff1a; 提高元素定位效率 启动&#xff1a;谷歌浏览器 按 F12 -&g…