字符函数与字符串函数(上)

个人主页(找往期文章包括但不限于本期文章中不懂的知识点):我要学编程(ಥ_ಥ)-CSDN博客

 

目录

strlen的使用与模拟实现

函数原型:

strlen的使用 

strlen的模拟使用 

strcpy的使用与模拟实现

函数原型:

strcpy的使用 

strcpy的模拟实现: 

strcat的使用与模拟实现 

函数原型:

strcat的使用 

strcat的模拟实现 

strcmp的使用与模拟实现 

函数原型:

strcmp的使用 

strcmp的模拟实现


strlen的使用与模拟实现

函数原型:

size_t strlen ( const char * str );//求字符串的长度

• 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。

• 参数指向的字符串必须要以 '\0' 结束。

• 注意函数的返回值为size_t,是无符号的

• strlen的使用需要包含头文件 <string.h>

• 学会strlen函数的模拟实现 

strlen的使用 

#include <stdio.h>
#include <string.h>
int main()
{char ch[] = "abcdef";//有'\0'结尾size_t ret = strlen(ch);printf("%zd\n", ret);return 0;
}

#include <stdio.h>
#include <string.h>
int main()
{char ch[] = { 'a','b','c' };//没有以'\0'结尾size_t ret = strlen(ch);printf("%zd\n", ret);return 0;
}

strlen的模拟使用 

方法1(计数器的方式):

#include <stdio.h>
#include <assert.h>//断言包含的头文件
size_t my_strlen(const char* str)
{size_t count = 0;assert(str);//不等于空指针程序正常运行while (*str)//当不等于'\0'时,进入{count++;str++;}return count;
}int main()
{char arr[] = "abcdef";size_t ret = my_strlen(arr);printf("%zd\n", ret);return 0;
}

方法2(指针-指针的方式) :

#include <stdio.h>
#include <assert.h>
size_t my_strlen(const char* str)
{assert(str);const char* str2 = str;//记录起始位置while (*str){str++;}return str - str2;//末地址-起始地址就是两者之间的元素个数
}int main()
{char arr[] = "abcdef";size_t ret = my_strlen(arr);printf("%zd\n", ret);return 0;
}

方法3(递归的方式):

#include <stdio.h>
#include <assert.h>
size_t my_strlen(const char* str)
{assert(str);if (*str == '\0'){return 0;//当为'\0'时,就返回}return 1 + my_strlen(++str);
}int main()
{char arr[] = "abcdef";size_t ret = my_strlen(arr);printf("%zd\n", ret);return 0;
}

递归存在一个限制条件,并且随着递归的深入越来越接近这个限制条件。这个限制条件应该是比较容易想到的, 就是等于'\0'的时候,写法和求n的阶乘类似。

strcpy的使用与模拟实现

函数原型:

char* strcpy(char * destination, const char * source );//字符串的拷贝

source是被拷贝字符串,即源字符串;destination是把字符串拷贝到这里,即目标字符串。其返回类型是char*,返回的是一个地址:目标字符串的起始地址。

• 源字符串必须以 '\0' 结束。

• 会将源字符串中的 '\0' 拷贝到目标空间。

• 目标空间必须足够大,以确保能存放源字符串。

• 目标空间必须可修改。(当目标空间有时,也是从源头开始拷贝,这也就导致了一个问题,目标空间原来的字符串被覆盖了。)

• 学会模拟实现。

strcpy的使用 

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = { 0 };//当目标空间不足时,也会完全拷贝,但是会报错char arr2[] = "abcdef";strcpy(arr1, arr2);printf("%s\n", arr1);printf("%s\n", arr2);return 0;
}

因此源字符串也是要以'\0'结尾,因为这样才能知道拷贝的具体内容。

#include <stdio.h>
#include <string.h>
int main()
{char arr1[10] = "abc";char arr2[] = "edf";strcpy(arr1, arr2);printf("%s\n", arr1);return 0;
}

如果要把 edf 搞到 abc 的后面需要用到另外一个函数strcat 。

上面这个就是目标空间不足时(会导致越界访问),报错界面。 

strcpy的模拟实现: 

根据前面的函数原型我们就可以开始来来模拟实现strcpy函数了。首先得想出思路:是将源字符串的字符赋值给目标空间,然后指向两者地址的指针往后走,直至遇到源字符串的'\0'就可以停止了。

#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* str1, const char* str2)
{assert(str1 && str2);//限制不为空指针char* p = str1;while (*str2)//当还没有遇到'\0'时,就继续拷贝{*str1 = *str2;str1++;str2++;}//因为我们要返回目标空间的初始地址,就得记录一下初始地址return p;
}int main()
{char arr1[20] = { 0 };char arr2[] = "abcdef";char* ret = my_strcpy(arr1, arr2);my_strcpy(arr1, arr2);printf("%s\n", ret);//ret接收的时arr1的初始地址,也就是首元素的地址printf("%s\n", arr1);//数组名是首元素的地址,因此这两个打印的结果是相同的return 0;
}

当然这个模拟实现strcpy的部分还可以简化一些。

#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* str1, const char* str2)
{assert(str1 && str2);//限制不为空指针char* p = str1;//这个可以根据优先级来理解:++(后置)> * > = ,由于是后置++,所以是先使用str1与str2//即*str1 与 *str2,再++,最后再赋值while(*str1++ = *str2++){;}//因为我们要返回目标空间的初始地址,就得记录一下初始地址return p;
}int main()
{char arr1[20] = { 0 };char arr2[] = "abcdef";char* ret = my_strcpy(arr1, arr2);my_strcpy(arr1, arr2);printf("%s\n", ret);printf("%s\n", arr1);return 0;
}

strcat的使用与模拟实现 

函数原型:

char * strcat ( char * destination, const char * source );//字符串的拼接(追加)

这些函数参数也是和strcpy一样的意义,source是要拼接的字符串,destination是被拼接的字符串。其返回的是char*,是目标空间的起始地址 

• 源字符串必须以 '\0' 结束。

• 目标字符串中也得有 '\0' ,否则没办法知道追加从哪里开始(在追加的时候会把这个'\0',给覆盖掉)。

• 目标空间必须有足够的大,能容纳下源字符串的内容。

• 目标空间必须可修改。

• 字符串自己给自己追加,如何? 

strcat的使用 

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "hello ";//当这个空间不足时,虽然依然会完全追加,但是会报错char arr2[] = "world";char* p = strcat(arr1, arr2);printf("%s\n", p);return 0;
}

当目标空间不足时,报错界面与上面的一样,也是越界访问导致的。

strcat的模拟实现 

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* str1, const char* str2)
{assert(str1 && str2);//控制不是空指针char* p = str1;//我们得先找到目标字符串的'\0',再在'\0'后追加while (*str1){str1++;}//当跳出这个while循环就代表我们已经找到这个'\0'的地址了,接下来开始追加while (*str2)//这个也可以和上面那个strcpy一样简化{*str1 = *str2;str1++;str2++;}*str1 = *str2;//因为while循环里没有把'\0'追加到目标字符串return p;
}int main()
{char arr1[20] = "hello ";char arr2[] = "world";char* ret = my_strcat(arr1, arr2);printf("%s\n", ret);printf("%s\n", arr1);return 0;
}

strcmp的使用与模拟实现 

函数原型:

int strcmp ( const char * str1, const char * str2 );//字符串的比较

str1与str2就是我们想要比较的字符串。其返回类型是 int  ,当str1 > str2时,返回大于0的数;当str1 == str2时,返回等于0的数;当str1 < str2时,返回0。比较两个字符串中对应位置上字符ASCII码值的大小。 而在比较时,是一个字符一个字符的比较。

例如:我们比较 abc 与 abq时,是 a 与 a 比较,当它们相等时,就比较下一个,会一直比较到两个字符不相等(当出现了字符不相等的时候,比较也就结束了。即使后面还有也不再比较),或者全部比较完。就像上面那个例子,当我们比较到 c 与 q 时,c < q,就会返回一个小于0的数字。(注意会比较到'\0'才停止

strcmp的使用 

#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abc";int ret = strcmp(arr1, arr2);printf("%d\n", ret);return 0;
}

#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abq";int ret = strcmp(arr1, arr2);//q>c,也就是arr1<arr2,输出一个小于0的数printf("%d\n", ret);return 0;
}

有细心的小伙伴可能会发现,这个arr1大于arr2,输出的是一个数字1。其实这个还是和编译器有关的,我这个是VS2022,大于0,输出的就是1;小于0,就是输出-1。 

strcmp的模拟实现

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* str1, const char* str2)
{assert(str1 && str2);while (*str1 == *str2){//本来是*str1 == *str2 == '\0',但因为*str1 == *str2,所以就简写if (*str1 == '\0'){return 0;}str1++;str2++;}//如果要和编译器一样的话,就可以写成:/*if (*str1 - *str2 > 0){return 1;}else if (*str1 - *str2 < 0){return -1;}*/return *str1 - *str2;//返回两者不相等的情况
}
int main()
{char arr1[] = "abcdef";char arr2[] = "abq";int ret = my_strcmp(arr1, arr2);printf("%d\n", ret);return 0;
}

上面这一系列函数是长度没有限制的。例如:在拷贝时,我们没有限制拷贝几个字符;在追加时,没有限制追加几个字符;在比较时,没有比较几个字符。但是如果我们想要限制长度,怎么实现呢?C语言库还给出了长度限制的一系列函数,这类函数就让我们下期一起来学习吧!。

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

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

相关文章

编译 qsqlmysql.dll QMYSQL driver not loaded

Qt 连接MySQL数据库&#xff0c;没有匹配的qsqlmysql.dll, 需要我们跟进自己Mysql 以及QT版本自行编译的。异常如下图&#xff1a; 安装环境为 VS2019 Qt5.12.12&#xff08;msvc2017_64、以及源码&#xff09; 我的安装地址&#xff1a;D:\Qt\Qt5.12.12 Mysql 8.1.0 默认安…

光谱数据处理:1.特征波长优选的不同方法与Python实现

首先&#xff0c;我们要理解为什么要对“光谱数据进行特征波长优选”以及这是在干嘛&#xff0c;光谱数据可以想象成一长串的彩色条纹&#xff0c;每种颜色对应一个波长&#xff0c;就像彩虹一样。这些颜色的条纹代表了从某种物质&#xff08;比如植物、矿石或是食品&#xff0…

线程安全的集合容器

线程安全的集合容器 List集合中的线程安全的集合容器&#xff1a; 在旧版本中Vector是线程安全的集合容器&#xff0c;在JDK 1.5以后CopyOnWriteArrayList也是线程安全的集合容器&#xff0c;CopyOnWriteArrayList的数据结构是Object类型的数组。 CopyOnWriteArrayList是如何…

基于JAVA的毕业设计分配选题系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 专业档案模块2.2 学生选题模块2.3 教师放题模块2.4 选题审核模块 三、系统展示四、核心代码4.1 查询专业4.2 新增专业4.3 选择课题4.4 取消选择课题4.5 审核课题 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpri…

事物管理(黑马学习笔记)

事物回顾 在数据库阶段我们已学习过事务了&#xff0c;我们讲到&#xff1a; 事物是一组操作的集合&#xff0c;它是一个不可分割的工作单位。事务会把所有的操作作为一个整体&#xff0c;一起向数据库提交或者是撤销操作请求。所以这组操作要么同时成功&#xff0c;要么同时…

SZTU抢课脚本python

声明:这篇代码是我基于我向我的部长学习的&#xff0c;带有一些理解和稍微一丢丢的改善&#xff0c;就是把他的一些模块套入到循环里这样可以一次性枪很多课&#xff0c;不过写的不是并发的所以会有顺序导致的无法同时抢很多课&#xff0c;而是抢完一个又一个 在这里也附上大佬…

android开发书籍推荐,android面试复习

笼统来说&#xff0c;中年程序员容易被淘汰的原因其实不外乎三点。 1、输出能力已到顶点。这个人奋斗十来年了&#xff0c;依旧碌碌无为&#xff0c;很明显这人的天花板就这样了&#xff0c;说白了&#xff0c;天赋就这样。 2、适应能力越来越差。年纪大&#xff0c;有家庭&…

qt5.15 升级 qt 6.5 部分问题 解决修复

报错 QT5_USE_MODULES 升级 QT6_ADD_RESOURCES qt_add_resources Compiles binary resources into source code. CMake Commands in Qt6 Core | Qt Core 6.6.2

HCIA-Datacom实验指导手册:6 构建基础 WLAN 网络

HCIA-Datacom实验指导手册&#xff1a;6 构建基础 WLAN 网络 一、实验介绍&#xff1a;二、实验拓扑&#xff1a;三、实验目的&#xff1a;四、配置步骤&#xff1a;1.掌握ap上线的配置方式和上线过程。ac配置验证 步骤 2 掌握隧道模式和旁挂模式下ac的配置。步骤 3 掌握查看ap…

4、正则表达式、本地存储

一、正则表达式 1、定义 用事先定义好的一些特定字符&#xff0c;这样的字符组合&#xff0c;组合成一个“规则字符串” 2、正则的组成 特殊字符 字母、数字、下划线、中文、特殊字符… 元字符&#xff08;常用&#xff09; 1、\d 匹配至少有一个数字 var reg /\d/ /…

【ElfBoard】基于 Linux 的智能家居小项目

大家好&#xff0c;我是 Hello阿尔法&#xff0c;这段时间参与了保定飞凌嵌入式技术有限公司举办的 ElfBoard 共创社招募活动&#xff0c;并有幸成为了一名共创官&#xff0c;官方寄来了一块 ELF 1 开发板&#xff0c;开箱看这里 ELF 1 开箱初体验。 作为共创官&#xff0c;我…

视频转字幕文字的方法有哪些?这些方法轻松搞定

怎么样通过视频链接将文字转化出来&#xff1f;当我们刷到一个喜欢的视频文案&#xff0c;想要复制出来已做借鉴&#xff0c;这个时候就需要用到一些神奇的AI工具。随着人工智能技术的不断发展&#xff0c;视频链接转文字已经变得越来越容易。现在市面上有很多在线工具可以将视…