超详细讲解字符串查找函数(保姆级教程!!!)

2023-05-16

超详细讲解字符串查找函数(保姆级教程!!!)

  • 字符串查找函数
    • strstr函数
      • strstr函数的使用
      • strstr函数的模拟实现
    • strtok函数
      • strtok函数的使用
      • strtok函数的模拟实现
    • strpbrk函数
      • strpbrk函数的使用
      • strpbrk函数的模拟实现
    • strcspn函数
      • strcspn函数的使用
      • strcspn函数的模拟实现
    • strspn函数
      • strspn函数的使用
      • strspn函数的模拟实现

字符串查找函数

strstr函数

在这里插入图片描述
strstr函数是在字符串 str1 中查找第一次出现字符串 str2的位置,不包含终止符 ‘\0’。
str1 – 要被检索的 C 字符串。
str2 – 在 str1 字符串内要搜索的小字符串。

strstr函数的使用

下面是strstr函数的使用例子:

/* strstr example */
#include <stdio.h>
#include <string.h>
int main ()
{
  char str[] ="This is a simple string";
  char * pch;
  pch = strstr (str,"simple");
  strncpy (pch,"sample",6);
  puts (str);
  return 0;
}

strstr函数的模拟实现

要在str1中查找str2并打印出来,先判断str1和str2指向的字符是否相等,此时有两种情况:
第一种情况指向的字符不相等,str1要指向下一个字符,再判断,如此循环往复,当str1指向的是 ‘\0’ 时,可以判断出str1中不存在str2,此时返回NULL;
第二种情况下指向的字符相等,那么不仅str1要向后读取字符,str2也要向后读取字符,再判断是否相等。
在这里插入图片描述
strstr函数的模拟实现如下:

char *  strstr (const char * str1, const char * str2) {
        char *cp = (char *) str1;
        char *s1, *s2;
        if ( !*str2 )
            return((char *)str1);
        while (*cp)
       {
                s1 = cp;
                s2 = (char *) str2;
                while ( *s1 && *s2 && !(*s1-*s2) )
                        s1++, s2++;
                if (!*s2)
                        return(cp);
                cp++;
       }
        return(NULL);

而实现strstr函数,除了上述的偏暴力算法的模拟实现方式之外,还可以通过KMP算法进行实现。
KMP算法:Knuth-Morris-Pratt 字符串查找算法,简称为 “KMP算法”,常用于在一个文本串S内查找一个模式串P 的出现位置,这个算法由Donald Knuth、Vaughan Pratt、James H. Morris三人于1977年联合发表,故取这3人的姓氏命名此算法。
算法的核心思想是:
假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置
如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++,继续匹配下一个字符;
如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]。此举意味着失配时,模式串P相对于文本串S向右移动了j - next [j] 位。
具体的KMP算法思想编者会另行写一篇文章向大家大致阐述,这里就不多在赘述,有兴趣的读者可以去了解一下。

strtok函数

在这里插入图片描述
char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。
str – 要被分解成一组小字符串的字符串。
delim – 包含分隔符的 C 字符串。
该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。

strtok函数的使用

下面演示strtok函数的用法:

#include <string.h>
#include <stdio.h>
 
int main () {
   char str[80] = "This is - www.xxxxx.com - website";
   const char s[2] = "-";
   char *tmp;
   tmp = strtok(str, s);
   while( tmp != NULL ) 
   {
      printf( "%s\n", tmp );
      tmp = strtok(NULL, s);
   }
   
   return(0);
}

编译并运行上面的程序将产生以下结果:
This is
www.xxxxx.com
website
原字符串的改动是切分符原位置均更改为 ‘\0’,所以内容都还在
strtok函数具有以下的特点:

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

strtok函数的模拟实现

char* my_strtok(char* str, const char* sep)
{
	static char* s1 = NULL;
	static char* s2 = NULL;
	static int len1 = 0;
	static int count = 0;
	int len2 = 0;
	int i = 0;
	assert(sep != NULL);
	if (str != NULL)               
	{
		s1 = str;                        
		len1 = strlen(str);
		len2 = strlen(sep);
		for (*str;*str != '\0';str++)        
		{
			for (i = 0;i < len2;i++)             
			{
				if (i == 0)
				{
					count++;
				}
				if (*str == *(sep + i))       
				{
					*str = '\0';           
					s2 = str;               
					return s1;
				}
			}
		}
	}
	else
	{
		s1 = s2 + 1;                        
		len2 = strlen(sep);
		str = s1;                         
		for (*str;*str != '\0';str++)       
		{
			for (i = 0;i < len2;i++)           
			{
				if (i == 0)
				{
					count++;
				}
				if (*str == *(sep + i))      
				{
					*str = '\0';       
					s2 = str;
					return s1;
				}
			}
		}
	}
	if (count > len1)
	{
		return NULL;
	}
	return s1;
}

strpbrk函数

在这里插入图片描述
char *strpbrk(const char *str1, const char *str2) 检索字符串 str1 中第一个匹配字符串 str2 中字符的字符,不包含空结束字符。也就是说,依次检验字符串 str1 中的字符,当被检验字符在字符串 str2 中也包含时,则停止检验,并返回该字符位置。
str1 – 要被检索的 C 字符串。
str2 – 该字符串包含了要在 str1 中进行匹配的字符列表。

strpbrk函数的使用

下面展示strpbrk函数的使用:

#include <stdio.h>
#include <string.h>
 
int main ()
{
   const char str1[] = "abcde2fghi3jk4l";
   const char str2[] = "34";
   char *ret;
 
   ret = strpbrk(str1, str2);
   if(ret) 
   {
      printf("第一个匹配的字符是: %c\n", *ret);
   }
   else 
   {
      printf("未找到字符");
   }
   
   return(0);
}

强调的是,找的是str1中,str2的第一个匹配的内容的地址。

strpbrk函数的模拟实现

char* find_char(char const* str1, char const* str2)
{
	assert(str1 != NULL);
	assert(str2 != NULL);

	char* tmp = (char*)str2;
	while (*tmp != '\0')
	{
		char* pso = (char*)str1;
		while (*pso != '\0')
		{
			if (*pso != *tmp)
			{
				++pso;
			}
			else
			{
				return pso;
			}
		}
		tmp++;
	}
	return 0;
}

strcspn函数

在这里插入图片描述

size_t strcspn(const char *str1, const char *str2) 检索字符串 str1 开头连续有几个字符都不含字符串 str2 中的字符。
str1 – 要被检索的字符串。
str2 – 该字符串包含了要在 str1 中进行匹配的字符列表。

strcspn函数的使用

下面演示strcspn函数的用法:

#include <stdio.h>
#include <string.h>


int main ()
{
   int len;
   const char str1[] = "ABCDEF4960910";
   const char str2[] = "013";

   len = strcspn(str1, str2);

   printf("第一个匹配的字符是在 %d\n", len + 1);
   
   return(0);
}

编译并运行上面的程序将产生以下结果:
第一个匹配的字符是在 10

strcspn函数的模拟实现

size_t my_strcspn(const char* str1, const char* str2)
{
	int i = 0;
	char* pstr1 = (char*)str1;

	assert(NULL != str1);
	assert(NULL != str2);

	while (*pstr1)
	{
		char* pstr2 = (char*)str2;
		while (*pstr2 && *pstr1 != *pstr2)
			++pstr2;

		if (*pstr1 == *pstr2)
			break;

		++pstr1;
	}

	return (pstr1 - str1);
}

strspn函数

在这里插入图片描述
size_t strspn(const char *str1, const char *str2) 检索字符串 str1 中第一个不在字符串 str2 中出现的字符下标。
str1 – 要被检索的字符串。
str2 – 该字符串包含了要在 str1 中进行匹配的字符列表。该函数返回 str1 中第一个不在字符串 str2 中出现的字符下标。

strspn函数的使用

下面演示 strspn函数的用法:

#include <stdio.h>
#include <string.h>

int main ()
{
   int len;
   const char str1[] = "ABCDEFG019874";
   const char str2[] = "ABCD";

   len = strspn(str1, str2);

   printf("初始段匹配长度 %d\n", len );
   
   return(0);
}

编译并运行上面的程序将产生以下结果:
初始段匹配长度 4

strspn函数的模拟实现

size_t my_strspn(const char* str1, const char* str2)
{
	int i = 0;
	char* pstr1 = (char*)str1;

	assert(NULL != str1);
	assert(NULL != str2);

	while (*pstr1)
	{
		char* pstr2 = (char*)str2;
		while (*pstr2 && *pstr1 != *pstr2)
			++pstr2;

		if (*pstr1 == *pstr2)
			break;

		++pstr1;
	}

	return (pstr1 - str1);
}

那么,今天的C语言 柔性数组的使用详解的相关内容我就讲述完啦,因为个人能力有限,文章难免会出现纰漏,届时有错误可以私信发给我以及时更正,谢谢大家!
请添加图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

超详细讲解字符串查找函数(保姆级教程!!!) 的相关文章

  • 一看就懂的java虚拟机内存区域划分

    一 虚拟机 同样的java代码在不同平台生成的机器码肯定是不一样的 xff0c 因为不同的操作系统底层的硬件指令集是不同的 同一个java代码在windows上生成的机器码可能是0101 xff0c 在linux上生成的可能是1100 xf
  • 硬核,20道经典Java基础面试题

    最近整理了20道Java基础面试题 xff0c 大家一起加油哈 1 ArrayList和LinkedList有什么区别 xff1f 可以从它们的底层数据结构 效率 开销进行阐述哈 ArrayList是数组的数据结构 xff0c Linked
  • 面向无人机的视觉目标跟踪算法:综述与展望

    摘要 近年来 无人机因其小巧灵活 智能自主等特点被广泛应用于民用和军事等领域中 特别是搜索侦察过程中首要的目标跟踪任务 无人机视觉目标跟踪场景的复杂性和运动目标的多变性 使得目标特征提取及模型建立困难 对目标跟踪性能带来巨大的挑战 本文首先
  • 网络空间对抗防御中的智能监测技术研究

    摘 nbsp nbsp 要 nbsp 网络空间数据流观测与威胁行为分析是国家网络空间安全防御中的重要方向 为 nbsp nbsp nbsp 应对国家网络空间大规模数据流观测和不断涌现的网络威胁对抗防御重大需求 针对传统 nbsp nbsp

随机推荐

  • Promethues (普罗米修斯)详细介绍

    目录 引言 一 Prometheus 概述 1 什么是Prometheus 2 Zabbix和Prometheus区别 3 Prometheus的特点 二 运维监控平台设计思路 三 Prometheus监控体系 1 系统层监控 xff08
  • 使用vue对表格数据进行查询

    大家好 xff0c 今天小明给大家带来一个带有查询框 的表格 xff0c 下面给大家瞅瞅效果图片 xff1a 带查询框的表格 xff0c 查询前的效果图 带查询框的表格 xff0c 查询后的效果图 从效果图上可以看出 xff0c 在查询框内
  • Linux操作系统面试总结

    1 系统启动流程 uboot gt kernel gt 根文件系统 uboot第一阶段属于汇编阶段 xff1a 定义入口 xff08 start S xff09 xff1a uboot中因为有汇编阶段参与 xff0c 因此不能直接找main
  • 详谈静态库和动态库的区别

    一 什么是库 xff1a 库是写好的 xff0c 现有的 xff0c 成熟的 xff0c 可以复用的代码 现实中每个程序都要依赖很多基础的底层库 xff0c 不可能每个人的代码都从零开始 xff0c 因此库的存在意义非同寻常 本质上来说 x
  • HDFS读取流程

    在HDFS的读写流程中 xff0c 主要是分为HDFS的读流程和写流程 其中先由HDFS写数据 xff0c 之后HDFS才可以读流程 HDFS写流程 Client向NameNode发送消息 xff0c 通过RPC与NameNode建立通信
  • 删除图片名与xml(json)文件名称不对应的

    1 文件夹下无目录文件夹 xff08 纯文件 xff09 import os def scanfile path 获取图片路径 xff08 列表格式 xff09 filelist 61 os listdir path for filepat
  • FreeRTOS内存不够

    STM32F103 xff0c RAM大小为20K xff0c 看起来还是很多的 xff0c 但一运行FreeRTOSG有点功能的程序马上就内存不够了 xff1b unable to allocate space for sections
  • FreeRTOS 任务之间运行时序

    操作系统 xff0c 我们肯定会创建许多任务 xff0c 而且任务的优先级不一样 xff0c 但我们一般情况是采用抢占模式 xff0c 也就是一直运行当前最高优先级任务 xff0c 那么其他低优先级任务就无法运行 xff0c 这时候需要通过
  • c语言-查找指定字符

    题目源自pta xff0c 侵删 本题要求编写程序 xff0c 从给定字符串中查找某指定的字符 输入格式 xff1a 输入的第一行是一个待查找的字符 第二行是一个以回车结束的非空字符串 xff08 不超过80个字符 xff09 输出格式 x
  • linux查看日志文件内容命令sed、cat、tac、more、less、head、tail、echo 1、按时间查询

    查询日志 xff1a linux查看日志文件内容命令sed cat tac more less head tail echo 1 按时间查询 sed n 39 2017 09 20 14 00 2017 09 20 15 00 p 39 c
  • 计算机保研面试经验分享—重庆大学

  • uCOS学习笔记——实时操作系统概述

    一 概述 RTOS real time operation system 既实时操作系统 通俗来说 xff0c 实时操作系统正如一个大管家一般 xff0c 可以根据任务的要求 xff0c 进行资源管理 xff0c 消息管理 xff0c 任务
  • windows HLK server部署操作步骤

    Windows Hardware Lab Kit HLK 微软官方提供的测试工具组 xff0c 也是微软的一种认证工具 xff0c 只有经过HLK测试过的windows系统 xff0c 官方才认可 The Windows Hardware
  • uCOS学习笔记----任务管理

    一 任务管理 一 任务的概念 从前文得知 xff0c uCOS可以将裸机中庞大的while 1 循环拆解为执行不同功能的小程序 xff0c 并依据一定的规则调度任务的运行 这些小程序就被称为任务 一般而言 xff0c 任务由三个部分构成 x
  • 想说说关于在刷题网站(牛客 、C语言网、力扣)上测试样例过了但是OJ判错这档子事

    目录 1 话题引入 2 在刷题过程中一些自己想说的 3 刷题时的一些小建议 4 个人感悟 1 话题引入 首先介绍一下我自己 xff0c 本人是一名专科大一的学生 xff1b 非计算机本专业 xff1b 因为想拓宽自己的知识面和技术 xff1
  • Java实现爬虫

    目录 xff1a 1 爬虫原理 2 本地文件数据提取及分析 3 单网页数据的读取 4 运用正则表达式完成超连接的连接匹配和提取 5 广度优先遍历 xff0c 多网页的数据爬取 6 多线程的网页爬取 7 总结 爬虫实现原理 网络爬虫基本技术处
  • Python+ADB脚本

    目录 准备工具 问题解决 xff1a 如何安装adb和python xff1f 编写程序 实现 注意 xff1a 准备工具 进入正题 xff0c 首先要准备的工具如下 1 一台正常的电脑且安装adb和python环境 2 一部安卓手机 4
  • (++i)+(++i)+(++i)计算的探讨

    今天在进行着代码选择题练习的时候 xff0c 我忽然看到了这一题 我左思右想 xff0c 发现答案应当是 xff08 2 xff09 43 xff08 3 xff09 43 xff08 4 xff09 61 9 xff0c 可我仍然保有着疑
  • 超详细讲解长度受限制的字符串函数(保姆级教程!!!)

    超详细讲解长度受限制的字符串函数 xff08 保姆级教程 xff01 xff01 xff01 xff09 长度受限制的字符串函数strncpy函数strncpy函数的使用strncpy函数的模拟实现 strncat函数strncat函数的使
  • 超详细讲解字符串查找函数(保姆级教程!!!)

    超详细讲解字符串查找函数 xff08 保姆级教程 xff01 xff01 xff01 xff09 字符串查找函数strstr函数strstr函数的使用strstr函数的模拟实现 strtok函数strtok函数的使用strtok函数的模拟实