C语言之字符函数字符串函数篇(2)

news2024/11/18 15:47:58

目录

字符串查找

strstr

strstr的使用

strstr的模拟实现 

分析 

考虑点 

代码 

strt

strtok的使用

循环改进 

错误信息报告 

strerror

错误码的错误信息

strerror的使用 

perror

字符操作

字符分类函数

字符转化函数


今天我们接着讲字符串函数,也会讲到字符函数。关于下面的字符串函数我们将从:作用  头文件  参数 返回值 等方面去介绍。🆗🆗

字符串查找

strstr

 strstr - C++ Reference

  •  strstr_string string库函数,是在字符串中找字符串
  • const char * strstr ( const char * str1, const char * str2 ); 本质上就是在str1去查找str2strstr会返回str1中str2第一次出现的位置如果str1中没有str2,返回NULL
  • 头文件#include<string.h>
  • 参数:两个字符串的指针
  • 返回值:str1中str2第一次出现的位置
  • strstr的模拟

strstr的使用

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcdefdhidefghi";
	char arr2[] = "def";
	const char* ret=strstr(arr1, arr2);
	//arr2第一次出现的位置
	if (ret == NULL)
		printf("找到不到");
	else
		printf("%s", ret);
	return 0;
}

 

strstr的模拟实现 

分析 

在我们的arr1中查找arr2中有很多种情况如下图: 

当然最后一种情况我们还可以分为比较复杂的情况如下图:

 

考虑点 

所以综上我们需要考虑:

  •  str1和str2一开始就为空情况
  • 在遍历过程中*s1为'\0' *s2为'\0'情况
  • 创建str1和str2去记录 记录arr1和arr2的起始位置
  • 创建s1和s2去遍历查找匹配比较
  • 创建cp为了记录可能匹配成功的arr1中arr2第一次出现位置的地址
  • 两个循环条件
  • 当情况比较复杂的时候,请不要改变字符串起始位置的指针变量,创建其他的指针去查询。
  • const
  • assert

代码 
#include<stdio.h>
#include<string.h>
const char* my_strstr(const char* str1, const char* str2)
{
	const char* cp;//记录开始匹配的位置,可能arr1中arr2第一次出现的位置
	const char* s1;//遍历str1指向的字符串
	const char* s2;//遍历str2指向的字符串
	//char*str1;
	//char*str2;
	
	assert(str1 && str2);
	cp = str1;//不改变初始位置的值
	while (*cp)//等于'\0'返回NULL
	{
		s1 = cp;//不改变cp的值
		s2 = str2;//不改变str2的值
		while (*s1 && *s2 && *s1 == *s2)
			//*s1 =='\0',arr1提前遇到'\0'找到不到了返回null
			//*s2 == '\0'arr2全部遍历匹配成功,返回此刻的cp
			//== 相等进入循环开始遍历匹配比较
		{
			s1++;
			s2++;
			//直到它们不相等跳出循环,找到下一个cp的位置继续查询
		}
		if (*s2 == '\0')
			return cp;
		//*s2 arr2全部匹配成功遇到'\0'
		//一开始*str2 == '\0'
		cp++;
	}
	return NULL;
	//一开始*str1 == '\0'
	//*s1 中途遇到'\0'(即arr1长度<arr2)
	//arr1全部遍历完也没有匹配的
}
int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";
	const char* ret = my_strstr(arr1, arr2);
	//arr2第一次出现的位置
	if (ret == NULL)
		printf("找不到");
	else
		printf("%s", ret);
	return 0;
}

#include<stdio.h>
#include<string.h>
const char* my_strstr(const char* str1, const char* str2)
{
	const char* cp;
	const char* s1;
	const char* s2;
	assert(str1 && str2);
	cp = str1;
	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return cp;
		cp++;
	}
	return NULL;
}
int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";
	const char* ret = my_strstr(arr1, arr2);
	if (ret == NULL)
		printf("找不到");
	else
		printf("%s", ret);
	return 0;
}

strt

strtok - C++ Reference

tsqxgd@yeah.net
192.168.101.23// IP地址_点分十进制的表示方法
//IP地址本来是一个无符号的整数,这种整数不方便记忆,所以将这个整数换成点分十进制的表示方法

分割符:
"@."//不讲究顺序
"."
char * strtok ( char * str, const char * sep );
  • 第二参数char *sep参数是个字符串,定义了用作分隔符的字符集合

  • 第一个参数char * str指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记

  • 头文件:#include<string.h>

  • 有可分割的字符串返回标记的指针

  • 无可分割的字符串返回NULL

  • 分割过程:

  1. strtok函数找到str中的一个标记。

  2. 利用sep找到这个标记的分隔符,并将标记用 \0 结尾(将标记末尾的分隔符改变成'\0')

  3. 返回一个指向这个标记的指针

  4. 保存这个标记在字符串中的位置(以方便分割下一个标记)。

  5. 特别注意:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改

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

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

  • 如果字符串中不存在更多的标记,则返回 NULL 指针。停止分割

  • 因为切割字符串的过程中会改变原字符串的内容,所以我们可以先拷贝到临时空间,再对临时空间进行拷贝。

  • 若分割符和分割符相邻,会跳过。

  • 那到底strtok是怎样保存标记在字符串的位置呢?可能是static

strtok的使用

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "tsqxgd@yeah.net";
	char buf[200] = { 0 };//放到临时的空间里,防止原arr被改变
	strcpy(buf, arr);
	char* sep = "@.";
	char* ret = strtok(buf, sep);
	printf("%s\n", ret);
	ret = strtok(NULL, sep);
	printf("%s\n", ret);
	ret = strtok(NULL, sep);
	printf("%s\n", ret);
	return 0;
}

 

循环改进 

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "tsqxgd@yeah.net";
	char buf[200] = { 0 };//放到临时的空间里,防止原arr被改变
	strcpy(buf, arr);
	char* sep = "@.";
	char* ret = NULL;//ret为空
	for (ret = strtok(buf, sep); ret != NULL; ret=strtok(NULL, sep))
	{
		printf("%s\n", ret);
	}
	return 0;
}

错误信息报告 

strerror

strerror - C++ Reference (cplusplus.com)

  •  strerror是库函数,将错误码翻译成错误信息,返回错误信息的字符串的起始地址
  • 头文件:#include<string.h>
  • 参数:错误码(整型)
  • 返回值:返回错误信息的字符串起始地址
  • C语言中使用库函数的时候,如果发生错误,就会将错误码放在errno的变量中。
  • errno是一个全局变量,可以直接使用
char * strerror ( int errnum );

错误码的错误信息

/* strerror example : error list */
#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)//错误码
	{
		printf("%d:%s\n", i, strerror(i));//错误信息
	}
	return 0;
}

 

strerror的使用 

那上面只是我们查看一下各个错误码对应的错误信息,那在具体的情况下,我们应该怎样使用呢?

/* strerror example : error list */
//打开文件的例子
//foopen以读的形式打开文件
//如果文件存在,打开成功
//如果文件不存在,打开失败
#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main()
{
	FILE* pFile;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
		printf("打开文件失败原因是: %s\n", strerror(errno));
	else
		printf("打开文件成功\n");
	return 0;
}

perror

perror - C++ Reference (cplusplus.com)

  •  直接打印错误码所对应的错误信息
  •  perror == printf +strerror
//打开文件的例子
//foopen以读的形式打开文件
//如果文件存在,打开成功
//如果文件不存在,打开失败
#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main()
{
	FILE* pFile;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
		perror("打开文件失败");
	//== printf+strerror
	else
		printf("打开文件成功\n");
	return 0;
}

字符操作

字符分类函数

关于字符分类函数我们就不一一讲解,大家通过查询网站,和从参数,返回值等方面去分析这些函数。注意字符函数的头文件是#include<ctype.h>

 <cctype> (ctype.h) - C++ Reference (cplusplus.com)

 中文表格 

字符转化函数

<cctype> (ctype.h) - C++ Reference (cplusplus.com)

#include <stdio.h>
#include <ctype.h>
int main()
{
	int ret = toupper('a');
	printf("%c\n", ret);
	ret = tolower(ret);
	printf("%c\n", ret);
	return 0;
}

我们用字符转化函数来实现一个简单的功能吧🆗🆗

将arr字符串数组中的大写转化成小写

#include <stdio.h>
#include <ctype.h>
int main()
{
	char arr[] = "Text String";
	//全部转化成小写
	int* p = arr;
	while (*p)
	{
		if (isupper(*p))
		{
			*p = tolower(*p);
		}
		p++;
	}
	printf("%s", arr);
	return 0;
}

 char类型可以放到int类型的变量中去;

 但是int类型不可以放到char类型的变量中去

✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正!下篇博文我们介绍内存函数。

希望我们都能够熠熠生辉,旗鼓相当。

代码------→【gitee:唐棣棣 (TSQXG) - Gitee.com】

联系------→【邮箱:2784139418@qq.com】

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

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

相关文章

Android 富文本SpannableString

一、认识SpannableString 为什么要使用富文本 在Android开发中&#xff0c;有很多UI会画出一些特别炫酷的界面出来&#xff0c;比如一个字符串里有特殊的字会有其他颜色并加粗、变大变小、插入小图片、给某几个文字添加边框&#xff0c;如果我们使用笨办法用几个TextView或者Im…

解决Spring Boot 2.7.16 在服务器显示启动成功无法访问问题:从本地到服务器的部署坑

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

JavaWeb 学习笔记 8:AJAX

JavaWeb 学习笔记 8&#xff1a;AJAX AJAX&#xff08;Asynchronous JavaScript And XML&#xff0c;异步 js 和 XML&#xff09;是一种用 js 代码异步&#xff08;或同步&#xff09;的方式请求服务端数据&#xff0c;并在页面显示或加载的技术。 1.快速入门 先看如何用纯 …

GB28181协议-注册详解

注册指的是设备或系统进入联网系统时向SIP服务器&#xff08;SIP UAS&#xff09;进行注册登记的工作模式&#xff0c;在本文中FFmpeg即为一个SIP服务器&#xff0c;设备向FFmpeg发送注册请求&#xff0c;FFmpeg在接收到设备的注册请求后返回相应的回复消息&#xff0c;则完成设…

【面试题】——Spring

1.Spring是什么&#xff1f; Spring是一个开源的Java应用框架&#xff0c;它提供了广泛的基础设施支持&#xff0c;用于构建Java应用程序。极大提高了开发效率。它提供了一种轻量级的编程模型&#xff0c;通过依赖注入&#xff08;Dependency Injection&#xff09;和面向切面…

盘点神级AI绘画工具,太强太友好了

B站|公众号&#xff1a;啥都会一点的研究生 AI绘画越来越卷、越来越极致&#xff0c;可以轻松将我们这些毫无绘画功底的人的创意想法转化为令人惊叹的数字艺术作品&#xff0c;本期将整理一些目前流行的高质量AI艺术生成器&#xff0c;一起看看吧 Bing Image Creator https:/…

污水中常规五参数的检测有什么意义

便携式水质五参数检测仪包括&#xff1a; 温度、 pH、溶解氧、电导率、浊度。同时该仪器也可根据客户需要进行其他电极法指标&#xff0c; 如盐度、 TD S、OR P 指标的增添&#xff0c;以及指标的任意搭配组合。 水质常规五参数在我国水污染防治中发挥着重要的作用。 检测水质常…

spring中AbstractApplicationContext的refresh()

这个部分的源码看的次数不计其数了&#xff0c;每次看不同开源组件的调用过程中走到这里都有不同的收获。 spring 中 AbstractApplicationContext 的 refresh() 是 spring 的核心&#xff0c;几乎所有的逻辑都在是这里间接被调用。 如下源码为 spring boot 2.7.15 自带的 sprin…

MySQL主从复制与读写分离(附配置实例)

目录 一、主从复制1.1 什么是主从复制&#xff1f;1.2 MySQL支持的复制类型1.3 主从复制的工作过程1.4 主从复制的同步模式1.4.1 异步复制&#xff08;Asynchronous replication&#xff09;1.4.2 全同步复制&#xff08;Fully synchronous replication&#xff09;1.4.3 半同步…

其他网页都可以打开,只有知网打不开

问题&#xff1a;电脑自动获取DNS出现问题。 1、打开Internet协议版本4&#xff08;TCP/IPv4&#xff09; 控制面板—所有控制面板项----网络连接----WLAN—属性----Internet协议版本4&#xff08;TCP/IPv4&#xff09;—属性 2、修改DNS 将自动获得DNS服务器地址&#xff…

Sparta工具用法描述之信息收集(漏洞分析)

声明:本文仅做学习与交流,任何用于非法用途、行为等造成他人损失的,责任自负。本文不承担任何法律责任。 Sparta是python GUI应用程序,它通过在扫描和枚举阶段协助渗透测试仪来简化网络基础结构渗透测试。 通过点击并单击工具箱并以方便的方式显示所有工具输出,它可以使测…

Swing通过后台线程实现页面更新

业务场景 在swing程序中&#xff0c;我们想实现一个随着任务的执行而同步更新组件的功能&#xff0c;如果在主线程&#xff08;EDT&#xff09;中直接执行任务并更新组件&#xff0c;则会导致组件只显示最终更新的状态的问题&#xff0c;这是因为EDT是单线程的&#xff0c;在执…

【golang】深入理解Go语言垃圾回收(GC)

垃圾回收 垃圾回收版本1.3之前标记-清除&#xff08;mark and sweep&#xff09;算法标记-清除&#xff08;mark and sweep&#xff09;的缺点 版本1.5的三色并发标记法没有STW的三色标记法屏障机制强-弱 三色不等式插入屏障删除屏障 版本1.8的混合写屏障&#xff08;hybrid wr…

MQ - 25 RabbitMQ集群架构设计与实现

文章目录 导图集群构建节点发现元数据存储数据可靠性镜像队列仲裁队列安全控制传输加密身份认证资源鉴权可观测性总结导图 集群构建 集群构建由节点发现和元数据存储两部分组成。RabbitMQ 也是一样的实现思路。 节点发现 在节点发现方面,RabbitMQ 通过插件化的方式支持了多…

经典题记录 字符串相加/相乘

1. LeetCode 415 字符串相加 代码一&#xff1a;代码简短&#xff0c;但需要借助额外的一个string来保存结果&#xff0c;更占用内存。 class Solution { public:string addStrings(string num1, string num2) {string ans"";int size1num1.size();int size2num2.si…

php之导入导出csv文件

一、导入csv文件 1、创建导入页面 <!DOCTYPE html> <html lang"zh-CN"> <meta charset"UTF-8"> <head><title>文件提交表单</title> </head> <body> <form action"test5.php" method"…

嵌入式裸机架构的探索与崩塌

为什么会想着探索下嵌入式裸机的架构呢&#xff1f;是因为最近写了一个项目&#xff0c;项目开发接近尾声时&#xff0c;发现了一些问题&#xff1a; 1、项目中&#xff0c;驱动层和应用层掺杂在一起&#xff0c;虽然大部分是应用层调用驱动层&#xff0c;但是也存在驱动层调用…

6年Android开发前10月的总结,写给正在求职的安卓开发

进入大厂工作对许多人来说已经是一种挑战&#xff0c;但只要充分准备&#xff0c;很多问题都可以逐步解决。当然&#xff0c;运气也起到了一定的作用&#xff0c;但最终还是与自身的努力密不可分。运气是实力的一部分&#xff0c;因为自助者天助。 每到10月进行总结时&#xff…

华为ICT——第二章-数字图像处理私人笔记

目录 1&#xff1a;计算机视觉&#xff1a;​编辑 2&#xff1a;计算机视觉应用&#xff1a;​编辑 3&#xff1a;计算机视界核心问题&#xff1a;​编辑 4&#xff1a;相关学科&#xff1a; 5&#xff1a;计算机视觉与人工智能&#xff1a; 最成熟的技术方向是图像识别 6…

Django应用及分布式路由

Django应用及分布式路由 应用 应用在Django项目中一个完全独立的业务模块&#xff0c;可以包含自己的路由&#xff0c;视图&#xff0c;模板&#xff0c;模型 应用配置 在这里面添加你自定义的应用 INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.cont…