字符串函数及其模拟实现

目录

  • strlen
    • 函数介绍
    • 模拟实现
  • strcpy
    • 函数介绍
    • 模拟实现
  • strcat
    • 函数介绍
    • 模拟实现
  • strcmp
    • 函数介绍
    • 模拟实现
  • strncpy
    • 函数介绍
    • 模拟实现
  • strncat
    • 函数介绍
    • 模拟实现
  • strncmp
    • 函数介绍
    • 模拟实现
  • strtok
  • strstr
    • 函数介绍
    • 模拟实现
  • strerror
    • perror

strlen

函数介绍

函数介绍:
字符串以’\0’作为结束标志,strlen函数返回的是在字符串中’\0’前面出现的字符个数(不包含’\0’)。
参数指向的字符串必须要以’\0’ 结束。
注意函数的返回值为size_t,是无符号的

模拟实现

计数方式:

int my_strlen(const char* str)//const修饰且在*左边,保证指向的内容不被改变
{int count = 0;assert(str);while (*str){count++;str++;}return count;
}

不创建变量方式(递归方式)

int my_strlen(const char* str)
{assert(str);if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}

指针 - 指针方式

int my_strlen(char* s)
{assert(str);char* p = s;while (*p != '\0')p++;return p - s;
}

strcpy

函数介绍

char* strcpy(char * destination, const char * source )
实现字符串拷贝,左参数是目标字符串的首地址,右参数是源字符串的首地址。
注意:
源字符串必须以‘ \0 ’ 结束。
strcpy会将源字符串的‘ \0 ’拷贝到目标空间中。
目标空间足够大,以确保能存放源字符串。
目标空间必须可变。

如果目标空间不够大,那么就会造成非法写入,然后报错。
拷贝的方法就是从源字符串的第一个字符开始一直到‘ \0 ’,如果源字符串的末尾没有以0结尾,就会一直读取,一直到0,这样就会非法访问。

模拟实现

方式1

void my_strcpy(char* str, const char* src)
{assert(str && src);while (*src){*str = *src;str++;src++;}*str = *src;
}

方式2,将方式1中while循环里面简化、

void my_strcpy(char* str, const char* src)
{assert(str && src);while (*str++ = *src++);
}

后置++,先使用再进行加操作,就算加了括号也是先使用再进行加操作。返回当前值,就是一直到str等于0的时候才停止循环。

方式3,增加返回值

char* my_strcpy(char* str, const char* src)
{char* ret = str;assert(str && src);while (*str++ = *src++);return ret;
}

strcat

函数介绍

char * strcat ( char * destination, const char * source )
字符串追加函数,在目标字符串后面追加源字符串,目标字符串的最后一个‘ \0 ’,被源字符串的第一个字符占据,追加完成以后会再新增一个‘ \0 ’。
注意:
源字符串必须以‘ \0 ’结束
目标字符串中也得有‘ \0 ’,否则没办法知道追加从哪里开始。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。

模拟实现

char* my_strcat(char* str, const char* src)
{char* ret = str;assert(str);assert(src);/*while (*str++ != '\0');在str等于0后要退出判断条件,此时会再进行一次加操作,后置加加不会因为要退出循环就不执行。str--;*/while (*str != '\0'){str++;}while (*str++ = *src++);return ret;
}

我们自己写的函数是无法自己给自己追加的,因为‘ \0 ’,被覆盖了,永远都不会遇到‘ \0 ’。但是库函数strcat可以 ,但是尽量不要这样使用,可以使用strncat来给自己追加。

strcmp

函数介绍

字符串比较函数
int strcmp ( const char * str1, const char * str2 )
第一个字符串大于第二字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字

比较规则是按照字典序比较的,如果是大小写的话就按照ASCII码值比较。ASCII码值大,那么字符串中的字符就大。如果一个字符串结束,另一个字符串就和‘ \0 ’,比较,此时就是‘ \0 ’小。

模拟实现

int my_strcmp(const char* str, const char* src)
{assert(str && src);while (*str == *src){if (*str == '\0')return 0;str++;src++;}return *str - *src;
}

strncpy

函数介绍

char * strncpy ( char * destination, const char * source, size_t num )
前两个参数和strcpy是一个意思,第三个参数是要拷贝的数量
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
如果字符串大于num,就拷贝num个,不补‘ \0 ’。

模拟实现

char* my_strncpy(char* str, const char* src, int num)
{char* ret = str;assert(str&& src);while (*str = *src){str++;src++;num--;if (num == 0)break;}while (num){*str = '\0';str++;num--;}return ret;
}

strncat

函数介绍

char * strncat ( char * destination, const char * source, size_t num )
指定在目标字符串后面追加多少个。
追加后补‘ \0 ’。
如果源字符串不够长,有多少个追加多少个。

模拟实现

char* my_strcat(char* str, const char* src, int num)
{char* ret = str;assert(str);assert(src);while (*str != '\0'){str++;}while (*str++ = *src++){num--;if (num == 0){*str = '\0';break;}}return ret;
}

strncmp

函数介绍

int strncmp ( const char * str1, const char * str2, size_t num )
比较前n个字符,返回值与strcmp相同。

模拟实现

int my_strncmp(const char* str, const char* src, int num)
{assert(str && src);while (*str == *src){num--;if (*str == '\0' || num <= 0)return 0;str++;src++;}return *str - *src;
}

strtok

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

int main()
{char arr[] = "zhangsan@qq.com.cn";char temp = { 0 };temp = strcpy(temp, arr);char* sep = ".@";char* str = NULL;for (str = strtok(arr, temp); str != NULL; str = strtok(NULL, temp)){printf("%s\n", str);}return 0;
}

strstr

函数介绍

const char * strstr ( const char * str1, const char * str2 )
在字符串中找字串,在str1中找str2
返回str2字符串在str1中第一次出现的第一个字符的地址,找不到就返回NULL。

模拟实现

char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* cp = str1;const char* s1 = NULL;const char* s2 = NULL;if (*str2 == '\0')//如果字符串是空return str1;while (*cp){s1 = cp;s2 = str2;while (*s1 == *s2 && *s2 && *s1){s1++;s2++;}if (*s2 == '\0')return cp;cp++;}return NULL;
}

strerror

strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。
使用strerror需要包含<string.h>

在C语言库函数中设计一些错误码,当我们库函数在调用的过程中发生了各种错误,要记录下来,这时候记录的就是错误码。
在这里插入图片描述

当库函数调用失败的时候会将错误码记录到errno这个变量当中,如过要使用这个变量需要引用<errno.h>这个头文件。
errno是一个C语言的全局变量。

比如我们打开一个文件,不存在那么打开失败,就会把失败的错误码存在errno里面

int main()
{FILE* pf = fopen("add.txt", "r");if (pf == NULL){printf("打开文件失败,原因:%s\n", strerror(errno));return 1;}else{printf("打开文件成功\n");}return 0;
}

在这里插入图片描述

perror

perror直接打印错误码所对应的信息,并且会打印参数,然后加一个冒号一个空格。
相当于printf和strerror(errno)的一个组合功能。

int main()
{FILE* pf = fopen("add.txt", "r");if (pf == NULL){perror("fopen");return 1;}else{printf("打开文件成功\n");}return 0;
}

在这里插入图片描述

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

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

相关文章

Leetcode 17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#xff1a; 输入&#xff1a;digits “23” 输出&#xff1a;[“a…

React真的好难用

我发现React就像个宗教一样&#xff0c;网络上总有一群信徒。信徒&#xff1a;React天下第一&#xff0c;谁也不能说他不好。 网络上大佬对React的评价一般有几类&#xff1a; React跟Vue比就是手动档和自动档的区别&#xff0c;高手都开手动档。—— 就一个破打工的&#xf…

cJSON的使用

文章目录 一、CJSON初识二、CJSON解析器基础三、CJSON解析数据JSON解析基础CJSON解析数组数据CJSON解析嵌套数据 五、创建JSON数据 一、CJSON初识 JSON (JavaScript Object Notation)是一种轻量级的数据交换格式&#xff0c;常用于在网络之间传输数据。它是一种文本格式&#…

河南新办灌溉排涝乙级资质预算分析

河南新办灌溉排涝乙级资质的预算分析是一个涉及多方面因素的综合考量。以下是对该预算的详细分析&#xff1a; 首先&#xff0c;人员费用是预算中的重要组成部分。这包括聘请符合资质要求的技术人员、工程师和其他相关人员的薪酬、社保等费用。这些费用会根据所需人员的数量、资…

JavaScript云LIS系统源码 前端框架JQuery+EasyUI+后端框架MVC+SQLSuga大型医院云LIS检验系统源码 可直接上项目

JavaScript云LIS系统源码 前端框架JQueryEasyUI后端框架MVCSQLSuga大型医院云LIS检验系统源码 可直接上项目 云LIS系统概述&#xff1a; 云LIS是为区域医疗提供临床实验室信息服务的计算机应用程序&#xff0c;可协助区域内所有临床实验室相互协调并完成日常检验工作&#xff…

Unity类银河恶魔城学习记录15-5,6 p157 Audio time limiter p158 Area sound

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili​​ AreaSound.cs using System.Collections; using System.Collections.G…

视频输入c++ 调用 libtorch推理

1、支持GPU情况 libtorch 支持GPU情况比较奇怪&#xff0c;目前2.3 版本需要在链接器里面加上以下命令&#xff0c;否则不会支持gpu -INCLUDE:?ignore_this_library_placeholderYAHXZ 2 探测是否支持 加一个函数看你是否支持torch&#xff0c;不然不清楚&#xff0c;看到…

Hive函数详解

Hive 是一个建立在 Hadoop 上的数据仓库基础架构&#xff0c;它提供了类似于 SQL 的查询语言&#xff0c;称为 HiveQL&#xff0c;用于对存储在 Hadoop 分布式文件系统中的数据进行查询和分析。 1.函数简介 Hive会将常用的逻辑封装成函数给用户进行使用&#xff0c;类似于Jav…

Web前端开发 小实训(一) 成绩分类统计

用于学生web前端开发课程实训练习&#xff0c;掌握基本语法和数据类型 实训目的 使用分支语句&#xff0c;完成分数统计与等级对比,通过输入框输入分数&#xff0c;可以根据分数多少划分等级。 参考思路&#xff1a; 分析题目&#xff1a;根据输入分数进行等级划分。 操作过…

springboot如何使用RedisTemplate

第一步&#xff1a;创建一个spring boot项目 第二步&#xff1a;pom导入redis相关依赖 <!--reids依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </depen…

Go语言中的goroutine调度是如何实现的?

文章目录 一、M:N调度模型二、GMP模型三、调度过程四、调度优化五、示例代码 在Go语言中&#xff0c;goroutine是一种轻量级的线程&#xff0c;它使得并发编程变得更加简单和高效。而goroutine的调度则是Go运行时&#xff08;runtime&#xff09;系统负责的一个核心任务&#x…

Postman,一个功能强大的API开发和测试工具

最近有小伙伴说在找 postman 的使用教程&#xff0c;案例等文章。 那么今天我就来写一个。 Postman 是一个功能强大的 API 开发和测试工具&#xff0c;它提供了丰富的功能&#xff0c;帮助开发人员更好地管理、测试和文档化 API。无论是单独开发还是团队协作&#xff0c;Postma…

[1688]jsp工资投放管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 工资投放管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0…

黑马面试篇

课程地址&#xff1a;新版Java面试专题视频教程&#xff0c;java八股文面试全套真题深度详解&#xff08;含大厂高频面试真题&#xff09;_哔哩哔哩_bilibili 课程名称&#xff1a;新版Java面试专题视频教程&#xff0c;java八股文面试全套真题深度详解&#xff08;含大厂高频…

Flutter - 折叠面板

demo 地址: https://github.com/iotjin/jh_flutter_demo 代码不定时更新&#xff0c;请前往github查看最新代码 flutter 自定义折叠组件 支持三种类型和两种展示效果可自定义title和被折叠的内容 效果图 示例 import package:flutter/material.dart; import /jh_common/widge…

基于SNAP使用SAR数据做变化检测change detection

基于SNAP使用SAR数据做变化检测change detection 1. 前言2. 步骤2.1 添加数据2.2 辐射定标--散斑过滤--地形矫正2.3 裁剪2.4 变化检测 3.查看变化检测结果 1. 前言 在SNAP中&#xff0c;change detection主要通过Stack工具来完成。 SAR数据&#xff1a;Radarsat-2 SLC 其他数据…

基于FastGPT搭建知识库问答系统

什么是 FastGPT &#xff1f; FastGPT 是一个基于 LLM 大语言模型的知识库问答系统&#xff0c;提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排&#xff0c;从而实现复杂的问答场景&#xff01; FastGPT 允许用户构建本地知识库&#xff0c;…

MQTT数据传输Payload的常见格式介绍

使用MQTT client过程中看到常见的数据格式&#xff1a; 下面是介绍 Plaintext&#xff08;纯文本&#xff09; 介绍&#xff1a;纯文本编码是最基本的编码形式&#xff0c;它使用标准的ASCII或Unicode字符来表示数据。这种编码格式是人类可读的&#xff0c;因为它直接表示文本信…

(成品论文22页)24深圳杯数学建模A题1-4问完整代码+参考论文重磅更新!!!!

论文如下&#xff1a; 基于三球定位的多个火箭残骸的准确定位 针对问题一&#xff1a;为了进行单个残骸的精确定位&#xff0c;确定单个火箭残骸发生音爆 时的精确位置和时间&#xff0c;本文基于三球定位模型&#xff0c;考虑到解的存在性和唯一性&#xff0c; 选取了四个监测…

第七篇、animateDiff使用

1、文生图 2、提示词游历 在不同帧设置不同的提示词&#xff0c;有公共提示词和游历提示词&#xff0c;上面是公共的&#xff0c;下面是游历