【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;elsereturn 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);elseprintf("找不到\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;		//不改变字符加constconst 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函数时将从’@'字符后面开始寻找下一个标记。

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

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

相关文章

【爱上C++】详解string类2:模拟实现、深浅拷贝

在上一篇文章中我们介绍了string类的基本使用&#xff0c;本篇文章我们将讲解string类一些常用的模拟实现&#xff0c;其中有很多细小的知识点值得我们深入学习。Let’s go&#xff01; 文章目录 类声明默认成员函数构造函数析构函数拷贝构造函数深浅拷贝问题传统写法现代写法…

泛型的使用(<T>)

文章目录 前言一、泛型是什么&#xff1f;二、泛型的使用 1.定义泛型类2.泛型的常规用法总结 前言 强制类型转换存在一定隐患&#xff0c;如数据丢失、内存溢出、运行时错误、程序逻辑错误等。所以提供了泛型机制&#xff0c;使程序员可以定义安全的数据类型进行操作。通俗的理…

CEPH 系统盘挂了,如何使用数据盘恢复

硬盘损坏是早晚的时&#xff0c;CEHP数据盘坏了&#xff0c;使用CEPH的基本都轻车熟路了&#xff0c;如果系统盘坏了呢&#xff1f;不知道的可能会采取整个系统盘全做的方式 前提条件&#xff1a;使用cephadm搭建集群 如果换服务器&#xff0c;请确保CEPH数据盘放到其它服务器上…

Python基础教程——一次搞懂 Python 字典!Python字典的20种神奇用法

Python 字典&#xff08;Dictionary&#xff09;是数据结构中的一种重要类型。它以键值对的形式存储数据&#xff0c;具有快速查找的特性。今天我们将通过生动有趣的案例&#xff0c;来探讨字典的20个经典操作&#xff0c;帮助大家深入理解和掌握这些概念。 1. 创建字典 字典…

Python从0到100(三十四):Python中的urllib模块使用指南

1. urllib模块概述 在Python中&#xff0c;除了广泛使用的requests模块之外&#xff0c;urllib模块也是处理HTTP请求的重要工具。urllib模块在Python 2中分为urllib和urllib2两个模块&#xff0c;而在Python 3中&#xff0c;它们被合并为一个urllib模块。本文将重点介绍Python…

【鸿蒙学习笔记】Column迭代完备

属性含义介绍 Column({ space: 10 }) {Row() {Text(文本描述).size({ width: 80%, height: 60 }).backgroundColor(Color.Red)}.width(90%).height(90).backgroundColor(Color.Yellow) } .width(100%) // 宽度 .height(200) // 高度 .backgroundColor(Color.Pink) // 背景色 .…

pcap包常见拆分方法

文章目录 Wireshark 拆分流量包SplitCap使用简介魔数报错示例结果 在进行流量分析时&#xff0c;经常需要分析pcap流量包。但是体积过大的流量包不容易直接分析&#xff0c;经常需要按照一定的规则把它拆分成小的数据包。 这里统一选择cic数据集里的Thursday-WorkingHours.pcap…

二、 操作系统知识(考点篇)

一、操作系统概述 操作系统定义&#xff1a; 能有效地组织和管理系统中的各种软/硬件资源&#xff0c;合理地组织计算机系统工作流程&#xff0c;控制程序的执行&#xff0c;并且向用户提供一个良好的工作环境和友好的接口。 操作系统有三个重要的作用&#xff1a; 第一&am…

【办公软件使用分享—Word篇】实用技巧 一学就会 沈阳电脑办公软件基础培训

在平时的工作学习中&#xff0c;Word真真是让很多人头疼的一件事&#xff0c;今天给大家分享20个案例&#xff0c;感受下Word真正的力量&#xff01; 1.插入自动目录 没有目录的文档不是一份合格的文档&#xff0c;很多人认为在Word里插入目录是一件很麻烦的事&#xff0c;其…

Soul打造安全社交元宇宙环境,全力守护用户线上社交安全

在数字化时代的浪潮中,智能安全线上社交正成为人们日常生活中的重要组成部分。随着人们对社交媒体和在线平台依赖程度的不断增加,保障个人信息安全和网络安全变得至关重要。在此背景下,社交平台致力于采取多种措施来保障用户的隐私安全,提升社交体验的质量和安全性。而Soul全方…

咖啡消费旺季到来 为何想转让的库迪联营商却越来越多

文 | 智能相对论 作者 | 霖霖 去年还在朝“三年万店”计划狂奔的库迪&#xff0c;今年已出现明显“失速”。 早在今年2月&#xff0c;库迪就官宣其门店数已超过7000家&#xff0c;如今4个多月过去&#xff0c;据极海品牌监测数据显示&#xff0c;截至6月27日&#xff0c;其总…

[Shell编程学习路线]——shell脚本中case语句多分支选择详解

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f6e0;️Shell编程专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月21日16点30分 &#x1f004;️文章质量&#xff1a;95分 ————前言———— 在Shell编程中&#xff0c;处理多种条件…

基于人脸68特征点识别的美颜算法(一) 大眼算法 C++

1、加载一张原图&#xff0c;并识别人脸的68个特征点 cv::Mat img cv::imread("5.jpg");// 人脸68特征点的识别函数vector<Point2f> points_vec dectectFace68(img);// 大眼效果函数Mat dst0 on_BigEye(800, img, points_vec);2、函数 vector<Point2f&g…

动手学深度学习(Pytorch版)代码实践 -计算机视觉-38实战Kaggle比赛:图像分类 (CIFAR-10)

38实战Kaggle比赛&#xff1a;图像分类 (CIFAR-10) 比赛链接&#xff1a;CIFAR-10 - Object Recognition in Images | Kaggle 导入包 import os import glob import pandas as pd import numpy as np import torch import torchvision from torch.utils.data import Dataset…

R语言数据分析案例39-合肥市AQI聚类和多元线性回归

一、研究背景 随着全球工业化和城市化的迅速发展&#xff0c;空气污染问题日益凸显&#xff0c;已成为影响人类健康和环境质量的重大挑战。空气污染不仅会引发呼吸系统、心血管系统等多种疾病&#xff0c;还会对生态系统造成不可逆转的损害。因此&#xff0c;空气质量的监测和…

MySQL高阶:事务和并发

事务和并发 1. 事务创建事务 2. 并发和锁定并发问题 3. 事务隔离等级3.1 读取未提交隔离级别3.2 读取已提交隔离级别3.3 重复读取隔离级别3.4 序列化隔离级别 4. 死锁 1. 事务 事务&#xff08;trasaction&#xff09;是完成一个完整事件的一系列SQL语句。这一组SQL语句是一条…

经典小游戏(一)C实现——三子棋

switch(input){case 1:printf("三子棋\n");//这里先测试是否会执行成功break;case 0:printf("退出游戏\n");break;default :printf("选择错误&#xff0c;请重新选择!\n");break;}}while(input);//直到输入的结果为假&#xff0c;循环才会结束} …

go Channel原理 (二)

Channel 设计原理 不要通过共享内存的方式进行通信&#xff0c;而是应该通过通信的方式共享内存。 在主流编程语言中&#xff0c;多个线程传递数据的方式一般都是共享内存。 Go 可以使用共享内存加互斥锁进行通信&#xff0c;同时也提供了一种不同的并发模型&#xff0c;即通…

error: Sandbox: rsync.samba in Xcode project

在Targets 的 Build Settings 搜索&#xff1a;User script sandboxing 设置为NO

python课程设计作业-TCP客户端-服务端通信

说明文档 目录 小组成员分工 作品功能介绍 使用的工具和方法 设计的步骤 课程设计中遇到的问题 结论 1. 小组成员分工 本次课程设计由以下小组成员完成&#xff1a; xxx 2. 作品功能介绍 本次课程设计的作品是一个简单的基于 TCP 协议的客户端-服务端通信示例。通过这个示…