字符串查找、错误信息、字符分类函数

news2024/12/25 10:27:35

1、寻找子串strstr

char* my_strstr(const char* str1, const char* str2)
{
    assert(str1 && str2);
    const char* cp = str1;
    const char* s1 = str1;
    const char* s2 = str2;
    while (*cp)
    {
        s2 = str2;
        s1 = cp;
        while (*s1!='\0' && *s2!='\0' && * s1 == *s2)
        {
            s1++;
            s2++;
        }
        if (*s2 == '\0')
        {
            return cp;
        }
            cp++;
    }
    return NULL;
}
int main()
{
    char arr1[] = "abbbcdef";
    char arr2[] = "bbc";
    char *ret=my_strstr(arr1, arr2);
    if (ret == NULL)
    {
        printf("不是子串\n");
    }
    else
    {
        printf("%s\n", ret);
    }
}

用cp标记每次查找的起始位置,s1每次从cp开始,s2从str2开始*s1=='\0'即找不到,*s2=='\0'即找到。cp为\0即在str1中无法找到子串。

2、字符串切割strtok

 1、每调用一次,在需要切割的函数里找 作为分隔符的任一字符,找到后置为\0 

2、第一次调用,需要传入这个字符串作为扫描的起始位置。完成调用,置为\0的位置会被记录,下次自动从\0的后一个位置开始扫描,因此后续调用传入NULL即可。

3、调用如果找到str的\0,本次调用还返回之前\0+1,但是后续所有的调用返回的都是NULL

利用while循环实现,循环前要先调用并打印一次。

巧妙利用for循环可以实现唯一一次初始化的特点,契合strtok函数的特点。

注意:strtok函数中涉及到对\0位置的标记和保存,在函数中保存而能在函数外使用,说明这个保存的指针类型应该用static关键字来修饰,即将这个变量附加一个静态属性,让它在函数外仍不被销毁,从而保存修改的\0的位置,进而下次使用strtok函数时直接调用。

同时,arr2字符串是一个常量字符串,内存是不可被改变的。第一个参数虽然可以传指针,但我们要考虑空间内存布局,用delim替换\0改变原字符串时,用指针指向这个字符串时,实际上指向的是字符串常量。

此处引用博主  Shemesz  提供的Linux下进程的内存布局图。

#include<string.h>
#include<stdio.h>
#include<assert.h>
// \0qq\0    com\0  next_start指向的是第一个q
//           @.\0
//     123456@qq.com.
char* my_strtok(char* str, const char* delim)
{
	static char* next_start = NULL;//第一次是NULL,后面的都不是NULL
	if (next_start != NULL)
	{
		str = next_start;
	}
	if(str==NULL && next_start == NULL)
	{
		return NULL;
	}
	char* s = str;//  str == 1  q   c
	const char* t = NULL;
	while (*s)
	{
		t = delim;
		while (*t)
		{
			if (*s == *t)
			{
				next_start = s + 1;
				if (s == str)//第一个元素就是要删除的,直接跳过,从下一个元素开始查找要删除的
				{
					str = next_start;
					break;
				}
				else
				{
					*s = '\0';
					return str;
				}
			}
			else
			{
				t++;
			}
		}
		s++;
	}
	//  s  t  都指向\0
	next_start = NULL;
	return str;
}
int main()
{
	//字符串切割strtok
	char arr1[] = "123456@qq.com";
	char arr2[] = "@.";
	char* ch = NULL;
	for (ch = my_strtok(arr1, arr2); ch != NULL; ch = my_strtok(NULL, arr2))
	{
		printf("%s\n", ch);
	}
}

原码实现。其中两个循环内部与strstr函数寻找子串并返回找到的地址相似。

两个循环走完后都没有返回,说明已经查找不到要切割的字符,因此返回最后一部分字符串。

再次调用my_strtok函数,经判断后返回NULL。

3、错误信息翻译官strerror

C语言的库函数在运行时如果发生一些错误,就会将错误码存放在一个全局变量errno中。错误码是一些数字,我们可以用strerror将错误码“翻译”成错误信息。 

0  没有错误

1  操作不被允许,没有权限

2  没有文件或文件夹

3  没有这个进程

4  函数调用被中断

5  输入输出错误 

以上是几个错误码对应错误信息的例子。但实际上,程序产生错误后把错误码存入errno中,我们可以直接打印errno。

前面调用库函数失败后,errno内的值更新为刚刚的错误码,然后才能被strerror翻译出来。

4、翻译并打印perror

 在打印错误信息前,先打印你自定义的信息。 

perror可认为是printf+strerror

当我们想打印错误信息时使用perror更方便,但是不想打印时就要使用strerror了。

头文件是stdio.h也是输出  使用errno 包含 errno.h  strerror是string.h

5、字符分类/判断/转换函数

1、分类、判断

iscntrl任何控制字符
isspace空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v'
isdigit十进制数字 0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A~Z
isalnum字母或者数字,a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

本质上内存中存的是字符的ASCLL码值,通过传入字符或其ASCLL码值判断是不是相应字符。

例如,islower判断是否是小写字母。返回int  0则不是,非0则是。

这一类函数本质上是相同的,可以灵活使用,忘记了就可以查一下再熟悉。 

3、转换

tolower  toupper

传入小写字符/或其ASCLL,返回其大写的字符/ASCLL

int main()
{
	char arr[] = "I Have An Apple";
	int i = 0;
	while (arr[i])
	{
		if (isupper(arr[i]))
		{
			printf("%c", tolower(arr[i]));
		}
		else
		{
			printf("%c", arr[i]);
		}
		++i;
	}	char arr[] = "I Have An Apple";
	//  是否实际改变数组内容   函数本身只是返回一个值  
	//  这是因为  传入的arr[i]为值传递,本身也改不了
	while (arr[i])
	{
		if (isupper(arr[i]))
		{
			arr[i] = tolower(arr[i]);
		}
			printf("%c", arr[i]);
		++i;
	}
	return 0;
}

 以上都是针对字符的函数。

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

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

相关文章

一步一步学爬虫(5)Ajax分析方法

一步一步学爬虫&#xff08;5&#xff09;Ajax分析方法5.2.1. 分析案例5.2.2. 过滤请求5.2.3. 总结5.2.1. 分析案例 这里还需要借助浏览器的开发者工具&#xff0c;下面以 Chrome 浏览器为例来介绍。 首先&#xff0c;用 Chrome 浏览器打开微博的链接 https://m.weibo.cn/u/283…

排查开机启动项

防止被控机器失联部分木马会添加开机启动项作为复活的手段 /etc/rc.local /etc/rc.local 是 /etc/rc.d/rc.local的软链接 [rootVM-4-11-centos etc]# ll rc.local lrwxrwxrwx 1 root root 13 Apr 6 2022 rc.local -> rc.d/rc.localrc.local的原始内容&#xff1a; #!/…

中文文案排版指北

格式规范千千万&#xff0c;内容创作 No.1 但是当下我们专注与文案排版。优秀的排版、正确使用标点符号能让阅读者赏心悦目&#xff0c;提升阅读体验。这篇文章将 GitHub 上的有关排版的规范摘抄部分供大家查阅&#xff0c;更多详情还请访问原文所在&#xff08;底部引用中的地…

APSIM练习:小麦苜蓿轮作

在本练习中&#xff0c;您将创建一个小麦苜蓿轮作&#xff0c;其中草料阶段持续数年。 基于“Rotation Sample.apsim”创建一个新的模拟。这是小麦鹰嘴豆轮作。在 Manager 文件夹中&#xff0c;Rotation Management 组件用于表示旋转&#xff0c;使用带有节点&#xff08;圆圈…

网站需要怎么优化比较好(网站优化有哪些技巧)

怎样让网站优化在短时间内看到效果&#xff1f; 在企业推广营销推广中&#xff0c;网站优化占据了很大一部分&#xff0c;对于企业推广营销有着决定性影响。如果想让您的企业在诸多品牌中脱颖而出&#xff0c;甚至在互联网中有强大的竞争力&#xff0c;你必须要做好网站优化&a…

基于微信小程序云开发的投票小程序源码,图文投票微信小程序源码

功能介绍 投票活动十分火&#xff0c;商家&#xff0c;企业&#xff0c;机构偶尔都会来一场投票活动评选&#xff0c;本小程序支持图文投票&#xff0c;简单方便、随时随地完成投票&#xff0c;可以方便设定投票模式&#xff08;按天按全程&#xff0c;投票数限定&#xff09;…

MySQL基础——DQL语句

select 聚合函数(字段列表) from 表名&#xff1b; Mysql的相关知识 好处 &#xff1a; 1.持久化数据到本地 2.可以实现结构化查询&#xff0c;方便管理 数据库主要分为: DB(数据库)&#xff0c;保存一系列有组织的数据容器。 DBMS(数据库管理系统)&#xff0c;用于对DB获得数…

[蓝桥杯 2017 省 B] k 倍区间(前缀和枚举/数论优化)

题目传送门 思路分析&#xff1a; 第一思路比较容易想到&#xff0c;就是枚举所有的前缀和&#xff0c;然后遍历它们计数满足题意的前缀和数量&#xff0c;最后输出即可&#xff0c;但是这里的数列最多达到了100000&#xff0c;在2层循环下&#xff0c;总的枚举次数就达到了O(…

webpack 的基本使用及配置

webpack 的基本使用配置 npm 镜像源创建列表隔行变色案例新建空白项目目录&#xff0c;初始化 package.json 配置文件通过 npm 安装 jquery新建 src 源代码目录index.htmlindex.js检查网页效果webpack 的安装webpack 的安装dependencies 与 devDependencies参数 -S 及 --save参…

规则引擎easy-rule快速入门及整合SpEL使用

规则引擎介绍 规则引擎解决的实际上就是判断条件分支过多的问题&#xff0c;举个例子&#xff0c;营销策略里&#xff0c;消费不足200&#xff0c;可用10元消费券&#xff0c;消费超过200元&#xff0c;可以享受9折优惠&#xff0c;超过400元和享受8折优惠。这里可以直接用if …

【houdini】带着uv进行模拟(冰激凌案例)

整个sop的路线图 前半部分&#xff1a;赋予材质并分离冰激凌球 一般模型是分部分的&#xff0c;比方说下面这个冰激凌的&#xff0c;分为5个部分。三个不同的冰激凌球和水和杯子。这些部分在houdini中被称为group。 用material节点一口气赋予5个group材质。 具体的材质的指…

【Linux】 gcc 、动态库和静态库,程序是如何链接的

文章目录前言一、gcc 是什么&#xff1f;二、使用步骤1.预编译2.编译3.汇编4.链接三、动静态库1.概念2.区别前言 在Linux环境下&#xff0c;除了学好编辑器 vim 的使用&#xff0c;还需要学会C语言的编译器 gcc 的功能&#xff0c;否则代码无法翻译成可执行程序。本文将介绍 gc…

怎样快速地迁移 MySQL 中的数据?

我们通常会遇到这样的一个场景&#xff0c;就是需要将一个数据库的数据迁移到一个性能更加强悍的数据库服务器上。这个时候需要我们做的就是快速迁移数据库的数据。那么&#xff0c;如何才能快速地迁移数据库中的数据呢&#xff1f;今天我们就来聊一聊这个话题。数据库的数据迁…

Spring Boot 日志详解

Spring Boot 日志一、日志有什么用二、日志怎么用三、自定义日志打印3.1 在程序中得到日志对象3.2 使用日志对象打印日志四、日志级别4.1 日志级别有什么用4.2 日志级别的分类与使用4.3 日志级别设置五、日志持久化5.1 配置文件名5.2 配置保存路径六、更简单的日志输出 -- lomb…

Go第 13 章 :2-客户信息关系系统

Go第 13 章 &#xff1a;2-客户信息关系系统 13.1 项目需求分析 模拟实现基于文本界面的《客户信息管理软件》。该软件能够实现对客户对象的插入、修改和删除&#xff08;用切片实现&#xff09;&#xff0c;并能够打印客户明细表 13.2 项目的界面设计 主菜单界面 添加客户…

SegFormer笔记(1)安装

一、代码地址github地址&#xff1a;https://github.com/NVlabs/SegFormer二、我的系统配置&#xff1a;1、硬件2、软件win10&#xff0c;vs2022&#xff0c;python3.7三、创建虚拟环境conda create -n MySegFormer python3.7 numpy conda activate MySegFormer python会显示如…

【知识图谱工具汇总】

一&#xff0c;图表示学习与计算框架 1&#xff09;PyTorch Geometric&#xff08;PyG&#xff09; 由德国多特蒙德工业大学研究者推出的基于PyTorch的几何深度学习扩展库。PyG在学术中是比较热门的框架&#xff0c;但是PyG对于异构图以及大规模的图的学习存在着较大的局限性…

【UE4 第一人称射击游戏】39-“M4A1”武器设置

上一篇&#xff1a;【UE4 第一人称射击游戏】38-拾取“M4A1”的提示信息步骤&#xff1a;在“AK47”文件夹中拷贝一份“Weapon_Base”拷贝到“M4A1”文件夹下&#xff0c;重命名为“Weapon_M4A1”打开“Weapon_M4A1”&#xff0c;新添加一个网格体组件骨架网格体选择“M4A1_wea…

Linux编辑器-gcc/g++使用

目录 背景&#xff1a; 预处理&#xff1a; 编译&#xff1a; 汇编&#xff1a; 连接&#xff1a; 静态连接&#xff1a; 动态连接&#xff1a; 自动化编程make/makefile&#xff1a; 背景&#xff1a; 我们知道任何一个c语言或者c文件想要生成一个可执行程序必须完成4个…

NotepadAttr

EntityMyPKAttr目录概述需求&#xff1a;设计思路实现思路分析1.Notepads2.EntityMyPK3.EntityMyPKAttr4.EntitiesMyPK5.EntityMyPKEntityMyPKAttrEntitiesMyPKWebContralBaseAtParaCashChartType参考资料和推荐阅读Survive by day and develop by night. talk for import biz …