C语言字符函数和字符串函数(1)

大家好,我们又见面了,让大家久等了,我们今天就来学习字符函数和字符串函数。

在这里插入图片描述

在开启今天的学习之前呢,我来解决一下一些小伙伴平时找不到库函数使用的烦恼,因为我们cplusplus.com最新版本不能够查询函数,我们需要去找我们需要使用的函数,所以就很麻烦,我们可以将它切换成老版本就可以进行查询了。
在这里插入图片描述

在这里插入图片描述
我们只要点击这个红色框就能够切换成老版本了。
在这里插入图片描述
然后我们点击红色框输入我们想要知道的函数就可以实现查询了。

1.strlen函数

在这里插入图片描述

我们以前接触过这个函数,这个函数是用来求字符串或字符长度的对吧,求的是‘/0’之前的字符个数。
我们在这里需要注意的是:
字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包
含 ‘\0’ )
参数指向的字符串必须要以 ‘\0’ 结束。
注意函数的返回值为size_t,是无符号的( 易错 )
学会strlen函数的模拟实现

那么我们怎么来使用它呢,我们看到代码:

#include <stdio.h>
#include<string.h>
int main()
{
const char*str1 = "abcdef";
const char*str2 = "bbb";
if(strlen(str2)-strlen(str1)>0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}

在这里插入图片描述

我们因为str1里面‘\0’前面有六个字符,所以strlen的结果就是6,而str2的结果就只有3,但是我们这里函数的返回类型size_t,也就是无符号数,我们得到的结果是-3,但是我们这里的结果之后也得转化为一个无符号数,就会是一个很大的正数,所以结果就会输出str2>str1。

那么怎么对这个函数模拟实现呢?

#include<stdio.h>
#include<assert.h>
#include<windows.h>int my_strlen(const char *str)
{int count = 0;assert(str != NULL);//断言,指针为空,打印出错误信息while (*str++)//遇到'\0'停止,不算'\0'{count++;}return count;
}int main()
{int len=0;char *p = "abcdef";len=my_strlen(p);printf("len=%d\n", len);system("pause");return 0;
}

在这里插入图片描述

这里我们要注意我们的传过去的*p,因为我们只求它的字符个数,所以我们不用改变它,就给它用const进行保护,我们为了防止空指针,所以要给它进行断言,我们在使用断言的时候,我们要加上头文件#include<assert.h>,因为我们这里是要求它的字符个数,所以我们需要碰到一个字符就给它计数,所以我们要定义一个计数器,并且对它初始化,我们接下来就利用循环结构就行,当我们碰到一个字符就计数,碰到‘\0’的时候得到’\0’,它的Ascall值为0,所以我们碰到‘\0’的时候就为假,就跳出循环了,最后在将结果返回主函数进行打印。

2.strcpy

在这里插入图片描述

源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
学会模拟实现。

接下来我们就给它模拟实现以下:

#include<stdio.h>
#include<string.h>
#include<assert.h>char* my_strcpy(char* dest, const char* src)
{char* ret = dest;assert(dest && src);while (*dest++ = *src++){;}return ret;
}int main()
{char arr1[20] = { 0 };char arr2[] = "abc";/*my_strcpy(arr1, arr2);printf("%s\n", arr1);*/printf("%s\n", my_strcpy(arr1, arr2));return 0;
}

在这里插入图片描述

我们这里定义两个字符数组,将这两个数组的地址传到我们自定义的函数my_strcat中,通过两个指针接收,这里我们依然要给它进行断言,因为我们要把第二个数组的元素拷贝到第一个元素当中,所以我们第二个元素是不变的,所以就用const对它进行保护,首先我们用一个循环找到数组的一个末尾,然后再循环将指针str中的内容拷贝到指针dest中,当dest为’/0’时,整个式子的结果为假就跳出循环。再将指针ret储存的数据返回进行打印。

3.strcat

在这里插入图片描述

连接函数
源字符串必须以 ‘\0’ 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
字符串自己给自己追加,如何

char* my_strcat(char* dest, const char* src)
{char* ret = dest;assert(dest && src);//1. 找到目标空间的末尾while (*dest != '\0'){dest++;}//2. 数据追加while (*dest++ = *src++){;}return ret;
}int main()
{char arr1[20] = "abc";strcat(arr1, arr1);//strncatprintf("%s\n", arr1);return 0;
}

在这里插入图片描述

在这里插入图片描述

在这个函数我们要知道连接函数strcat和拷贝函数strcpy一样,我们要连接的数组是从上一个数组的‘/0’开始,而且第二个数组的‘\0’也会连接到上一个数组作为结束的标志。所以当我们字符串自己给自己追加也会打印出结果。我们在这里也要进行断言,为了防止变成空指针。

4.strcmp

在这里插入图片描述

比较字符串函数:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字

那么我们怎么去比较两个字符串的大小呢?我们其实是比较两个字符串函数之间对应位置字符的ASCLL值的小,如果前一个相同的话就比较下一个,一直比较下去直到比较出大小为止。
在这里插入图片描述

int my_strcmp(const char* str1, const char* str2)
{assert(str1 && str2);while (*str1 == *str2){if (*str1 == '\0')return 0;str1++;str2++;}return *str1 - *str2;
}int main()
{char arr1[] = "abq";char arr2[] = "abc";if (my_strcmp(arr1, arr2) > 0){printf(">\n");}else{printf("<=\n");}return 0;
}

在这里插入图片描述

我们这里将两个数组的地址传到函数中,我们进入循环中,如果第一个字符的值都相等,如果此时的str1=‘/0’的话,那么str2也为’\0’,所以两个字符串大小相等,如果str1!=0,那么我们就进行下一个字符的比较,最后返回str1-str2到主函数中进行判断和打印结果。

5.strncpy, strncat,strncmp

我们看到这里的三个函数和上面我们刚学的一些函数有些相似,那么我们就以strcpy和strncpy函数为例来讲解。
在这里插入图片描述

我们发现下面这个函数多了一个参数,而且是一个无符号数的参数,那么这个参数具体的作用是什么呢?其实这个参数是进行限制作用的,我们这个拷贝函数,如果给num一个值,那么num就是我们拷贝过去的字符个数。

int main()
{char arr1[20] = { 0 };char arr2[] = "abcdefghi";strncpy(arr1, arr2, 3);printf("%s\n", arr1);return 0;
}

在这里插入图片描述
因为我们这里传的参数是3,所以我们只拷贝三个字符上去,所以得到的结果是abc。

int main()
{char arr1[20] = "abc\0xxxxxxxxxxxxxx";char arr2[] = "defghi";strncat(arr1, arr2, 10);printf("%s\n", arr1);return 0;
}

在这里插入图片描述

我们这里用的连接函数是10个字符,所以我们全部都可以连接上去。但是我们要注意拷贝的时候如果我们要拷贝10个字符上去,而我们这个数组少于10个字符的时候后面多的位置就会补充’\0’,而我们的连接函数则不会补充’\0’,这就是这两个函数的区别。另外两个也是类似的,这里就不一一进行讲解了。

6.strstr

在这里插入图片描述
上面这个是c++,而下面这个才是我们C语言的库函数。这个函数的作用呢就是在一个字符串里找到我们出现的字符串。也就是说要从我们str1里面找到str2的字符串。

#include<stdio.h>
#include<assert.h>
const char* my_strstr(const char* str1, const char* str2)
{const char* cp;//记录开始匹配的位置const char* s1;//遍历str1指向的字符串const char* s2;//遍历str2指向的字符串assert(str1 && str2);if (*str2 == '\0')return str1;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("找不到\n");}else{printf("%s\n", ret);}return 0;
}

在这里插入图片描述
在这里插入图片描述

在做这个题的时候我们需要用到多个指针,因为我们要两个指针指向刚开始的位置,用另外的指针去移动,在用指针给储存起来,在这里我们的s1和s2指针是用来遍历的,我们先用if语句进行判断,如果我们的str2为’\0’时,就返回str1,因为我们在集合中就已经知道空集合是任意集合的子集,当我们的str2指针为’\0’时,我们才会将str1的指针用cp来接收,然后我们将cp指针和str2指针分别赋给s1和s2指针,前提是cp不能为不能为’\0’,然后我们进入下一个循环,当s1和s2为’\0’和s1与s2相等时,我们就给他们进行下一个字符的比较,如果不相等我们就跳出循环,跳出循环后要对指针s2进行判断,如果我们的s2指针为’\0’的话,我们就返回cp,cp++我们就下一个字符作为第一个字符开始遍历,如果一直到指针cp为’\0’的时候都没有找到,那就返回NULL空指针。

7.strtok

在这里插入图片描述

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

这个函数的作用是用分隔符将我们的一些字符串给分隔开,而我们将分隔符储存到一个指针sep中,当我们需要用到的时候就给它传参就行了。

int main()
{char arr[] = "zpengwei@yeah.net";char buf[200] = {0};//"zpengwei@yeah.net"strcpy(buf, arr);char* p = "@.";char* s = strtok(buf, p);printf("%s\n", s);s = strtok(NULL, p);printf("%s\n", s);s = strtok(NULL, p);printf("%s\n", s);return 0;
}

在这里插入图片描述

我们将分隔符@和.存入一个指针p中,当我们对字符串进行操作的时候我们就取分隔符前面的字符串,并且将分隔符的位置保存下来,然后我们想要对下面的字符串进行打印的话,就要重复对字符串进行该函数操作,不过这里传参不同,我们传参的第一个位置变成了空指针NULL,而我们的就会从上一次标记的地方开始,找到下一个分隔符,将字符串输出。

8. strerror

在这里插入图片描述

这个函数的作用是返回错误码,所对应的错误信息。

#include<errno.h>
int main()
{int i = 0;for (i = 0; i < 10; i++){printf("%d: %s\n", i, strerror(i));}return 0;
}

在这里插入图片描述

在使用这个函数我们会用到全新的头文件,这个我们要记得,然后由于我们这个函数的作用是返回错误码所对应的信息,我们就可以利用循环来查看0到9的错误码所代表的信息。

好了,学到这里大家一定都很累了吧,我们今天的学习就到这里了,我们下次再见,谢谢大家。

在这里插入图片描述

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

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

相关文章

排查disabled问题之谷歌新版本特性

问题复现 最近我突然接手一个后台的bug&#xff0c;这个后台很久没有迭代更新了&#xff0c;我也不熟悉业务&#xff0c;所以只能看一下源码&#xff0c;问题很快就复现&#xff0c;测试的修复操作也很正确&#xff0c;就是因为渲染的input标签中存在disableddisabled’属性导…

英国留学生务必谨慎使用ChatGPT!!!

ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;是OpenAI研发的聊天机器人程序&#xff0c;于2022年11月30日发布。ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;它能够基于在预训练阶段所见的模式和统计规律…

1.IAR-8051安装

新版安装教程&#xff1a;IAR EW for 8051 简介与安装 新版软件zhuce&#xff1a;IAR EW for 8051 软件注册 - 知乎 这个新版的我也放到网盘里面了&#xff0c;自己自行选择安装 一、下载IAR-8051 链接&#xff1a;https://pan.baidu.com/s/1mYwSQvSjAiSzltrEbK3yAw?pwd43cd …

【产品经理】深入B端SaaS产品设计核心理念

这几年各企业的B端业务都在做SaaS平台&#xff0c;但对SaaS的了解还不是完全全面&#xff0c;对于一些产品的定位以及设计还在探索中 本文讨论“为什么采用SaaS模式”、“SaaS产品有哪些”以及“如何做好SaaS产品设计”三个话题&#xff0c;核心是产品设计&#xff0c;主要从需…

LabVIEW开发航天器模拟器的姿态控制和反作用轮动量管理

LabVIEW开发航天器模拟器的姿态控制和反作用轮动量管理 在过去十年中&#xff0c;航天器一直是现代技术进步的先决条件。迄今为止&#xff0c;为了更好地完成各种实际任务&#xff0c;已经在航天器姿态控制领域进行了大量研究。航天器一旦进入太空&#xff0c;就容易出现不确定…

CSS

CSS CSS是什么 层叠样式表 (Cascading Style Sheets).CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果. 能够做到页面的样式和结构分离.说白了就是让网页变得好看 什么是样式呢&#xff1f; 大小&#xff0c;位置&#xff0c;间距&#xff0c;颜色&a…

银行发展绿色金融,8条建议为您指路

在《财富潮涌&#xff1a;银行发展绿色经济创新路径》内容中&#xff0c;我们带大家了解了商业银行有关绿色财富、绿色服务及绿色运营的内容。今天&#xff0c;我们将阐述商业银行发展绿色金融的必要性以及在实践中商业银行应该如何发展色金融。 发展绿色金融的必要性与难点 1.…

华为杯数学建模比赛经验分享

再过一周左右,第二十届华为杯数学建模比赛就要开赛了&#xff0c;所以今天分享一下个人数学建模比赛的经验。 今天给大家分享一期关于华为杯数学建模比赛的经验分享&#xff0c;我将从以下三个方面展开说明&#xff1a; &#xff08;1&#xff09;如何准备数学建模比赛&#x…

Interceptor的使用场景:拦截请求中的租户信息,注入到租户上下文中

业务场景 在SaaS环境中&#xff0c;租户是最重要的隔离业务数据的属性了&#xff0c;在自己的项目体系环境中&#xff0c;租户id能保证有值。但有个特殊场景&#xff0c;某些特殊权限的账号需要修改指定租户的内容&#xff0c;也即前端会携带租户信息过来&#xff0c;并且内部涉…

共享单车场景下Cat.1网络表现如何?测试结果来了

为帮助行业客户提高Cat.1产品稳定性&#xff0c;近期&#xff0c;天翼物联组织终端客户郑州威科姆科技股份有限公司开展基于中国电信 Cat.1网络下的共享单车体验测试&#xff0c;内容涵盖单车实时位置监控、单车在线率、业务数据延迟、语音播报功能等。测试结果表明&#xff0c…

零基础学前端(四)1. 重点讲解 CSS:盒子模型、样式选择器

1. 该篇适用于从零基础学习前端的小白 2. 初学者不懂代码得含义也要坚持模仿逐行敲代码&#xff0c;以身体感悟带动头脑去理解新知识 3. 初学者切忌&#xff0c;不要眼花缭乱&#xff0c;不要四处找其它文档&#xff0c;要坚定一个教授者的方式&#xff0c;将其学通透&#xff…

uni-app:通过ECharts实现数据可视化-如何引入项目

效果 引入文件位置 代码 <template><view id"myChart"></view> </template> <script> import echarts from /static/js/echarts.js // 引入文件 export default {mounted() {// 初始化EChartsconst myChart echarts.init(document…

中秋特辑:Java事件监听实现一个猜灯谜小游戏

众所周知&#xff0c;JavaSwing是Java中关于窗口开发的一个工具包&#xff0c;可以开发一些窗口程序&#xff0c;然后由于工具包的一些限制&#xff0c;导致Java在窗口开发商并没有太多优势&#xff08;当然也有一些第三方的工具包也很好用&#xff09;&#xff0c;不过&#x…

【卷积神经网络】ResNets 残差网络

通常来说&#xff0c;增加卷积神经网络的层数有利于提高模型的准确率&#xff0c;但是深层的神经网络也变得难以训练的&#xff0c;因为存在梯度消失与梯度爆炸问题。Microsoft 亚洲研究院的 Kaiming He 等人提出了一个残差学习框架&#xff0c;以简化对 CNN 网络的训练。通过将…

基于SpringBoot+Vue的餐饮管理系统设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…

Linux 挂载

挂载需要挂载源和挂载点 虚拟机本身就有的挂源 添加硬件 重启虚拟机 操作程序 sudo fdisk -l //以管理员权限查看电脑硬盘使用情况sudo mkfs.ext4 /dev/sdb //以管理员身份格式化硬盘sudo mkdir guazai //创建挂载文件夹 sudo mount /dev/sdb/guazai //将挂载源接上挂载点 s…

嵌入式C语言知识复习和提高

文章目录 前言基础知识main函数防BUG注释&#xff08;重要&#xff09;关键字标识符命名&#xff08;驼峰命名&#xff09;常量类型变量printf1.输出不同类型数据2.输出不同宽度数据3.不同类型数据长度归类 scanf函数运算符sizeof&#xff08;运算符&#xff0c;优先级2&#x…

欧拉操作系统在线安装mysql8数据库并用navicat premium远程连接

网上太多安装教程&#xff0c;但是没有一个教程能够一站式解决安装问题&#xff0c;而我不一样&#xff0c;我写的每一个博客&#xff0c;都是我自己试验过很多次&#xff0c;能够确保一站式解决&#xff0c;才会发上去&#xff0c;希望能够帮助到大家 第一步&#xff1a;升级…

恒合仓库 - 仓库管理系统搭建

仓库管理系统搭建 文章目录 仓库管理系统搭建一、项目介绍1.1 项目描述1.2 技术选型1.3 模块划分 二、搭建前端环境三、搭建后端环境3.1 创建springboot项目 - 划分包层次3.2 导入依赖3.3 启动类配置3.4.配置文件配置 一、项目介绍 1.1 项目描述 项目搭球为满足日益扩大的仓库…

Matlab图像处理-区域描述

一旦一幅图像的目标区域被确定&#xff0c;我们往往用一套描述子来表示其特性。选择区域描述子的动机不单纯为了减少在区域中原始数据的数量&#xff0c;而且也应有利于区别带有不同特性的区域。因此&#xff0c;当目标区域有大小、旋转、平移等方面的变化时&#xff0c;针对这…