C语言--字符串函数1
目录
- 前言
- strlen
- strlen的模拟实现
- strcpy
- strcat
- strcat的模拟实现
- strcmp
- strcmp的模拟实现
- strncpy
- strncat
- strncmp
- strstr
- strchr和strrchr
- strstr的模拟实现
前言
本章我们将重点介绍处理字符和字符串的库函数的使用和注意事项。
strlen
我们先来看一个我们最熟悉的求字符串长度的库函数–strlen
#include <stdio.h>
#include <string.h>int main()
{int len = strlen("abcdef");printf("%d", len);return 0;
}
运行结果如图1
这里有几点是值得我们注意的:
- 字符串已 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ ).
- 参数指向的字符串必须要以‘\0’结束。
- 注意函数的返回值是size_t,是无符号的。
strlen的模拟实现
模拟实现strlen的方法有很多种,例如计数器方法,递归方法,指针减去指针的方法,我们以指针减指针为例。
#include <stdio.h>
#include <assert.h>int my_strlen(const char* str)
{int count = 0;assert(str);while (*str != '\0'){count++;str++;}return count;
}int main()
{char arr[100] = "abcdef";int ret = my_strlen(arr);printf("%d", ret);return 0;
}
strcpy
库函数strcpy在之前的博客中有十分详细的讲解,这里就不做过多赘述了
模拟实现库函数–strcpy
这里我们只需要注意以下几点即可
-
源字符串必须以 ‘\0’ 结束。
-
目标空间必须足够大,以确保能存放源字符串.
如图2就是错误示范
-
目标空间必须可变
如图3就是错误示范
strcat
stract函数的作用是将一段字符串追加到另一端字符串的末尾。
代码实现如下
int main()
{char arr1[20] = "Hello ";char arr2[20] = "World";strcat_s(arr1, arr2);printf("%s", arr1);return 0;
}
其中arr1是被追加对象,而arr2是追加对象。运行结果如图4
我们知道在Hello 的末尾有一个\0,那么在arr2追加的时候有没有将这个\0给覆盖掉呢,我们主动添加一个\0来看效果。
int main()
{char arr1[20] = "Hello \0********";char arr2[20] = "World";strcat_s(arr1, arr2);printf("%s", arr1);return 0;
}
我们调试一下观察变化,如图5,6
我们发现\0是被覆盖掉了的。所以在追加的时候是从\0开始的。
我们在使用这个函数的时候要注意以下几点
- 源字符串必须以 ‘\0’ 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容.
- 目标空间必须可修改.
strcat的模拟实现
我们先来看代码
char* my_strcat(char* dest, const char* src)
{assert(dest && src);//将最初的arr1的首元素地址保存起来char* ret = dest;//找目标空间中的\0while (*dest != '\0'){dest++;}while (*dest++ = *src++){;}return ret;
}
int main()
{char arr1[20] = "Hello ";char arr2[20] = "World";my_strcat(arr1, arr2);printf("%s", arr1);return 0;
}
我们通过画图来分析一下:
strcat可以自己给自己追加吗?
这需要用到后面优化过后的strncat函数,strcat函数本身是不适合自己追加自己的,这是因为每当覆盖过后,\0会消失,*dest找不到\0了,于是会继续往下找,这样就会陷入一个死循环当中。
strcmp
相信strcmp的作用读者应该也是再熟悉不过了,它的作用就是比较两个字符串大小。
举两个简单的例子
arr1 = "abcdef";
arr2 = "bbd";
strcmp(arr1,arr2);
a大于b所以返回一个大于0的数
arr1 = "abcdef";
arr2 = "abad";
strcmp(arr1,arr2)
从第一个元素开始依次比较,前两个元素都相等,到第三个是,由于a的ascll码值比b大,所以arr2大于arr1,返回一个小于0的数
为什么返回的值是大于小于零的数呢?因为标准规定:
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
由此可见,strcmp的返回值必须要用有符号类型接收
strcmp的模拟实现
先来看代码
int my_strcmp(const char* str1, const char* str2)
{assert(str1 && str2)while (*str1 == *str2){if(*str1 == '\0')return 0;str1++;str2++;}if (*str1 > *str2)return 1;elsereturn -1;}
int main()
{char arr1[20] = "abcdef";char arr2[20] = "adq";int ret = my_strcmp(arr1, arr2);printf("%d", ret);return 0;
}
以上面代码为例,比较结果如图7
所以arr2是小于arr1的。
前面我们介绍的库函数都是长度不受限制的函数,是不安全的,所以在c语言中还引入了一系列长度受到限制了的字符串函数,下面我们继续来介绍长度受限制的字符串函数。
strncpy
strncpy在传递参数的时候就要比strcpy函数多传递一个数参数,意思是只拷贝这么多个参数。
int main()
{char arr1[] = "abcdef";char arr2[5] = "xxx";strncpy(arr2, arr1, 3);printf("%s", arr2);return 0;
}
代码运行结果如图8
这样相对来讲就会更安全一些。
strncat
有了刚刚strncpy对于对于参数的理解,这个函数理解也大同小异
int main()
{char arr1[20] = "hello ";char arr2[] = "abcdef";strncat_s(arr1, arr2, 3);printf("%s", arr1);return 0;
}
追加的结果如图9
通过这个函数,我们就能实现字符串自己对自己追加的效果,因为多了一个长度的限制,所以可以避免死循环导致程序崩溃的情况。
strncmp
在strncmp中的个数代表的是要比较几个元素,看下面这段代码
int main()
{char arr1[20] = "abcdef ";char arr2[] = "abcqqq";int ret = strncmp(arr1, arr2, 3);printf("%d", ret);return 0;
}
由于只比较了三个元素,所以比较的结果应该是相等的,返回值应该为0,运行结果如图10
strstr
这个函数的作用是在str1中找str2出现第一次的位置。找到了就返回首次出现的地址。没找到就返回空指针。
先来看代码
int main()
{char arr1[] = "abcdef";char arr2[] = "bcd";char* p = strstr(arr1, arr2);if (p == NULL){printf("找不到");}else{printf("%s", p);}return 0;
}
strchr和strrchr
strchr和strstr的效果很类似,是在str1中找一个字符首次出现的位置,而strrchr是找这个字符在str1中最后一次出现的位置。
对这两个函数分别举一个例子:
int main()
{char arr1[] = "abcdef";char a = 'b';char* p = strchr(arr1, a);if (p == NULL){printf("找不到");}else{printf("%s", p);}return 0;
}
打印结果如图11
int main()
{char arr1[] = "abcdebf";char a = 'b';char* p = strrchr(arr1, a);if (p == NULL){printf("找不到");}else{printf("%s", p);}return 0;
}
打印结果如图12
strstr的模拟实现
代码如下
char* my_strstr(const char* str1, const char* str2)
{char* s1 = NULL;char* s2 = NULL;char* cp = (char*)str1;while (*cp){s1 = cp;s1 = (char*)str2;while (*s1 && *s2 && *s1 == *s2){s1++;s2++;}if (*s2 == '\0'){return cp;}cp++;}return NULL;
}int main()
{char arr1[] = "abcdebf";char arr2[] = "cde";char* p = my_strstr(arr1, arr2);if (p == NULL){printf("找不到");}else{printf("%s", p);}return 0;}
我们通过图解来分析,如图13
以上就是本章全部内容,如有出入,欢迎大佬们指正。
相关文章:
C语言--字符串函数1
目录前言strlenstrlen的模拟实现strcpystrcatstrcat的模拟实现strcmpstrcmp的模拟实现strncpystrncatstrncmpstrstrstrchr和strrchrstrstr的模拟实现前言 本章我们将重点介绍处理字符和字符串的库函数的使用和注意事项。 strlen 我们先来看一个我们最熟悉的求字符串长度的库…...
Webstorm使用、nginx启动、FinalShell使用
文章目录 主题设置FinalShellFinalShell nginx 启动历史命令Nginx页面发布配置Webstorm的一些常用快捷键代码生成字体大小修改Webstorm - gitCode 代码拉取webstorm 汉化webstorm导致CPU占用率高方法一 【忽略node_modules】方法二 【设置 - 代码编辑 - 快速预览文档 - 关闭】主…...
源码分析Spring @Configuration注解如何巧夺天空,偷梁换柱。
前言 回想起五年前的一次面试,面试官问Configuration注解和Component注解有什么区别?记得当时的回答是: 相同点:Configuration注解继承于Component注解,都可以用来通过ClassPathBeanDefinitionScanner装载Spring bean…...
vector的使用及模拟实现
目录 一.vector的介绍及使用 1.vector的介绍 2.vector的使用 1.vector的定义 2.vector iterator的使用 3. vector 空间增长问题 4.vector 增删查改 3.vector 迭代器失效问题(重点) 1. 会引起其底层空间改变的操作 2.指定位置元素的删除操作--erase 3. Li…...
“华为杯”研究生数学建模竞赛2007年-【华为杯】A题:基于自助法和核密度估计的膳食暴露评估模型(附获奖论文)
赛题描述 我国是一个拥有13亿人口的发展中国家,每天都在消费大量的各种食品,这批食品是由成千上万的食品加工厂、不可计数的小作坊、几亿农民生产出来的,并且经过较多的中间环节和长途运输后才为广大群众所消费,加之近年来我国经济发展迅速而环境治理没有能够完全跟上,以…...
刷题(第三周)
目录 [CISCN2021 Quals]upload [羊城杯 2020]EasySer [网鼎杯 2020 青龙组]notes [SWPU2019]Web4 [Black Watch 入群题]Web [HFCTF2020]BabyUpload [CISCN2021 Quals]upload 打开界面以后,发现直接给出了源码 <?php if (!isset($_GET["ctf"]))…...
新C++(14):移动语义与右值引用
当你在学习语言的时候,是否经常听到过一种说法,""左边的叫做左值,""右边的叫做右值。这句话对吗?从某种意义上来说,这句话只是说对了一部分。---前言一、什么是左右值?通常认为:左值是一个表示数据的表达式(…...
TCP相关概念
目录 一.滑动窗口 1.1概念 1.2滑动窗口存在的意义 1.3 滑动窗口的大小变化 1.4丢包问题 二.拥塞控制 三.延迟应答 四.捎带应答 五.面向字节流 六.粘包问题 七.TIME_WAIT状态 八.listen第2个参数 九.TCP总结 一.滑动窗口 1.1概念 概念:双方在进行通信时&a…...
MySQL锁篇
MySQL锁篇 一、一条update语句 我们的故事继续发展,我们还是使用t这个表: CREATE TABLE t (id INT PRIMARY KEY,c VARCHAR(100) ) EngineInnoDB CHARSETutf8;现在表里的数据就是这样的: mysql> SELECT * FROM t; —------- | id | c | —…...
SWF (Simple Workflow Service)简介
Amazon Simple Workflow Service (Amazon SWF) 提供了给应用程序异步、分布式处理的流程工具。 SWF可以用在媒体处理、网站应用程序后端、商业流程、数据分析和一系列定义好的任务上。 举个例子,下图表明了一个电商网站的工作流程,其中涉及了程序执行的…...
java(Class 常用方法 获取Class对象六种方式 动态和静态加载 类加载流程)
ClassClass常用方法获取Class对象六种方式哪些类型有Class对象动态和静态加载类加载流程加载阶段连接阶段连接阶段-验证连接阶段-准备连接阶段-解析初始化阶段获取类结构信息Class常用方法 第一步:创建一个实体类 public class Car {public String brand "宝…...
【数据结构】线性表和顺序表
Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 1.线性表 2.顺序表 2.1 静态顺序表 2.2 动态顺序表 2.3移除元素 1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线…...
Ubuntu数据库安装(mysql)
##1.下载mysql-apt-config_0.8.22-1_all.deb并且安装 wget https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb sudo dpkg -i mysql-apt-config_0.8.22-1_all.deb##2.更新apt-updata sudo apt update##3.如果出现如下图情况执行以下命令 [外链图片转存失败,源站可…...
MyBatis-Plus的入门学习
MyBatis-Plus入门学习简介特性快速开始MyBatis-Plus的注解详解Tableld主键生成策略1、数据库自动增长 AUTO2、UUID3、Redis生成id4、MP主键自动生成TableNameTableField自动填充测试方法:update乐观锁select查所有根据id查多个id批量查询简单条件查询(通…...
华为OD机试题 - 内存池(JavaScript)
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:内存池题目输入输出示例一输入输出说明Code解题思路版权说明华为…...
数据库索引原理
数据库索引的作用是做数据的快速检索,而快速检索实现的本质是数据结构。像二叉树、红黑树、AVL树、B树、B树、哈希等数据结构都可以实现索引,但其中B树效率最高。MySQL数据库索引使用的是B树。二叉树:二叉树中,左子树比根节点小&a…...
字符函数和字符串函数详解(1)
目录前言strlen函数strlensizeofstrcpy函数strcat函数strcmp函数总结前言 最近要调整状态,写的文章质量不佳让大家失望,我现在也在反思我在做什么,我会什么,我学了什么。等我想明白的那天,我一定能跟大家顶峰相见的&a…...
【数据分析:工具篇】NumPy(1)NumPy介绍
【数据分析:工具篇】NumPy(1)NumPy介绍NumPy介绍NumPy的特点数组的基本操作创建数组索引和切片数组运算NumPy介绍 NumPy(Numerical Python)是Python的一个开源的科学计算库,它主要用于处理大规模的多维数组…...
mysql时区问题
设置mysql容器时间与服务器时间一致 问题背景: 今天测试发现一个问题,时间不一致,当工单入库时,其创建时间和更新时间应该是一样的,即使不一样最多只会错几秒的时间;实际上两个时间相差的大概8小时&#…...
磨金石教育摄影技能干货分享|高邮湖上观花海
江苏高邮,说到这里所有人能想到的,就是那烟波浩渺的高邮湖。高邮在旅游方面并不出名,但是这里的自然人文景观绝对不输于其他地方。高邮不止有浩瀚的湖泊,春天的油菜花海同样壮观。春日的午后,与家人相约游玩࿰…...
mysql navicat忘记密码
mysql忘记密码是常用的事情,那么如何解决它呢?1、首先将MySQL的服务关闭,两种方法:(1)打开命令行cmd输入net stop mysql命令即可关闭MySQL服务。(2)打开任务管理器,找到服…...
Git的下载、安装、配置、使用、卸载
前言 我是跟着狂神老师学的。该博客仅用于笔记所用。 下面是老师的B站和笔记 B站:https://www.bilibili.com/video/BV1FE411P7B3?p1&vd_source9266cf72b1f398b63abe0aefe358d7d6 笔记:https://mp.weixin.qq.com/s/Bf7uVhGiu47uOELjmC5uXQ 一、准备工…...
【博客631】监控网卡与进程网络IO使用情况
监控进程的网络IO使用情况 1、vnstat 由于 vnstat 依赖于内核提供的信息,因此执行以下命令来验证内核是否提供了 vnStat 所期望的所有信息: # vnstat --testkernel This test will take about 60 seconds. Everything is ok.不带任何参数的 vnstat 将…...
【Leetcode】【简单】35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2 示例 2: 输入:…...
sql面试题
mysql优化 优化准则: 建表时:合理选择字段的类型,单表字段数量 sql查询尽量单表操作,避免复杂操作,复杂的多表通过java代码实现 构建复合索引优化,索引尽量可以覆盖主要业务查询 sql避免索引失效 避免大…...
SQL 进阶刷题笔记
SQL 进阶刷题笔记 一、MySQL 进阶 这里主要是 MySQL 刷题相关笔记,方便后面温习和查阅,希望可以帮到大家!!! 题1 请计算每张SQL类别试卷发布后,当天5级以上的用户作答的人数uv和平均分avg_score࿰…...
[网鼎杯 2020 朱雀组]Think Java
SqlDict.java ,其中sql语句处存在sql注入漏洞 package .sqldict;import cn.abc.core.sqldict.Row; import cn.abc.core.sqldict.Table; import java...
AIR32F103(十) 在无系统环境和FreeRTOS环境集成LVGL
目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告AIR32F103(二) Linux环境和LibOpenCM3项目模板AIR32F103(三) Linux环境基于标准外设库的项目模板AIR32F103(四) 27倍频216MHz,CoreMark跑分测试AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码AIR32F103(六) ADC,I2S…...
SpringBoot接口 - 如何统一异常处理
SpringBoot接口如何对异常进行统一封装,并统一返回呢?以上文的参数校验为例,如何优雅的将参数校验的错误信息统一处理并封装返回呢?为什么要优雅的处理异常如果我们不统一的处理异常,经常会在controller层有大量的异常…...
如何使用Python进行数据可视化
数据可视化是一种将数据呈现为图形或图表的技术,它有助于理解和发现数据中的模式和趋势。Python是一种流行的编程语言,有很多库可以帮助我们进行数据可视化。在本文中,我们将介绍使用Python进行数据可视化的基本步骤。 第一步:导…...
网站文章标题/百度网站推广排名优化
原文首发于博客园,作者:后青春期的Keats 地址:https://www.cnblogs.com/keatsCoder/ Linux 配置优化 我们在使用 Redis 过程中,可能更多的关注 Redis 本身的一些配置优化,如 AOF、RDB 配置、数据结构配置优化等。 但…...
全网营销推广网站建设/网站优化是什么意思
当页面使用 utf-8 编码时,<title>标签被放在<meta>标签前面。当title为中文的时(比如Blog名为中文或者文章标题为中文),在IE下会出现显示空白页的问题。由于 utf-8 使用3个字节表示一个汉字,而GB2312或BIG5使用两个字节。页面输出…...
电脑上做简单的网站/优化服务是什么意思
1 简介 通用Mapper都可以极大的方便开发人员。可以随意的按照自己的需要选择通用方法,还可以很方便的开发自己的通用方法。 极其方便的使用MyBatis单表的增删改查。 支持单表操作,不支持通用的多表联合查询。 通用 Mapper 支持 Mybatis-3.2.4 及以上…...
营销网络建设体系/关键词优化怎么弄
2019独角兽企业重金招聘Python工程师标准>>> Mac OS X 10.6即所谓的Snow Leopard操作系统已正式发售。一如既往,Apple产品光鲜的外表下凝聚了太多艰辛的劳作。ArsTechnic的John Siracusa以其独特的、专业的、全面的视角深入翔实地体验这款最新的操作系统…...
日照 网站 建设/网页链接制作生成
由于工作需要,我要实现web表单的自动提交功能。最近网站改版在线编辑器采用了KindEditor,用原来的软件不能继续工作了,经过一周努力,终于实了再次自动提交上报的功能,现在总结记录如下。 一、原来网站提交的方式&#…...
深圳做网站网络公司怎么样/域名whois查询
先说说购机原因吧,原来的本子用了两年半,配置有点过时,确实是想换个新的,又碰巧10月份是我的本命年的生日,理应庆贺一下,老婆也十分的体贴我,非常大方的让我随意选购,只要我喜欢的&a…...