C语言中字符串相关的函数解析

        C语言中没有string类型,字符串通常放在常量字符串字符数组中,下面来介绍一些常用的字符串相关的操作函数。

strlen

        strlen用来求一个字符串的长度,其函数原型如下:

size_t strlen ( const char * str );

        使用strlen需要注意以下几点:

①strlen求的是字符串中\0前面的字符个数(不包括\0),所以字符串必须\0结尾

②strlen返回值类型是size_t,也就是unsigned int,是无符号整型,如果两个strlen相减是不能得到负数的。

        下面用两种方法来模拟实现一下strlen:

//方法1,常规方法int My_Strlen(char *str){int num = 0;while (*str != '\0'){num++;str++;}return num;}//方法2,递归int My_Strlen_1(char *str){if (*str != '\0'){return My_Strlen_1(str + 1) + 1;//这里不能用str++,因为后置++是先执行再++,会死循环,++str也不推荐,虽然可以实现,但是str也被改变了}return 0;}

strcpy

        strcpy用于拷贝源空间的字符串到目标空间,其函数原型如下:

//source是源字符串首地址,Destination是目标字符串首地址,返回的是目标字符串的首地址
char* strcpy(char * destination, const char * source);

        使用该函数需要注意以下几点:

①源字符串必须以\0结尾。

②该函数会把源字符串中\0之前的字符连同\0一起拷贝到目标地址。

③目标空间必须足够大,保证能存放源字符串

④目标空间必须是可变的,不能是常量字符串。

        下面来模拟实现一下strcpy:

/** @brief    拷贝字符串初阶代码* @param    dest: 要拷贝的目标地址* @param    src: 要拷贝的源地址*/
void my_strcpy(char *dest, char *src)
{while (*src != '\0') // 判断scr还没有结束{*dest = *src; // 把src中的字符复制到dest中dest++;src++;}*dest = *src; // strcpy会把\0也一起拷贝
}
/** @brief    改进的字符串拷贝函数* @param    dest: 要拷贝的目标地址* @param    src: 要拷贝的源地址* @return   char*: 返回目标空间的起始地址,也就是最初的dest*/
// 增加返回值是为了实现链式访问,函数的返回值可以作为其他函数的参数
char *my_strcpy_01(char *dest, const char *src) // 在源地址加入const是为了防止写函数时while等号两边写反,如果加上const,写反会报错
{char *ret = dest;assert(dest && src);             // 增加断言,防止输入参数误传为NULL,如果误传会报错while (*dest++ = *src++) ;// 较上述代码有所简化,当*src为\0时,赋值后表达式会为0,会跳出循环return ret;
}

strcat

        strcat用于在目标字符串后追加源字符串,其函数原型如下:

//source是源字符串地址,destination是目标字符串地址,返回的是目标字符串地址
char * strcat ( char * destination, const char * source );

        使用该函数需要注意以下几点:

①源字符串必须以\0结尾。

②目标空间必须足够大,保证能存放源字符串

③目标空间必须是可变的,不能是常量字符串。

         下面举一个使用示例:

int main()
{char arr[20] = "hello ";strcat(arr,"world");printf("%s\n",arr);//会打印hello world
}

        下面来模拟实现一下strcat:

/** @brief    字符串追加函数* @param    destination:目标字符串地址* @param    source:源字符串地址* @return   char*:返回目标字符串地址*/
char *my_strcat(char *destination, const char *source)
{assert(destination && source);//断言防止输入NULLchar *dest = destination;while (*destination++) ;// 先找出目标字符串的末尾,也就是\0destination--;                     // 此时destination就是\0的位置while (*destination++ = *source++) ;// 然后与字符串拷贝同理return dest;
}

strcmp

        strcmp用于比较两个字符串是否相等,比较的是每一个字符的ASCII码值的大小,其函数原型如下:

//str1是第一个字符串的地址,str2是第二个字符串的地址,
//如果第一个字符串大于第二个字符串,返回大于0的数,如果小于,返回小于0的数,如果等于,返回0
int strcmp ( const char * str1, const char * str2 );

        下面举一个例子:

int main()
{char arr1[10] = "abc";char arr2[20] = "abc";
//这样比较两个字符串是否相等是不对的,因为arr1和arr2是数组名,就是数组首元素的地址,直接用等号比比的是地址的大小,而不是两个字符串相比if(arr1 == arr2)printf("arr1 == arr2\n");elseprintf("arr1 != arr2\n");
//判断两个字符串是否相等应该用下面的方法,并且strcmp比较的不是字符串的长度,而是ASCII码,abc是比abbbbbbb要大的if(strcmp(arr1,arr2) > 0)printf("arr1 > arr2\n");else if(strcmp(arr1,arr2) < 0)printf("arr1 < arr2\n");elseprintf("arr1 == arr2\n");
}

         下面来模拟实现一下strcmp:

/** @brief    字符串比较函数,如果str1>str2,输出正数,反之输出负数,相等输出0,比较的不是长度,是ASCll码* @param    str1:* @param    str2:* @return   int:*/
int my_strcmp(const char *str1, const char *str2)
{assert(str1 && str2);// 遍历两字符串,如果找到不相等的退出循环,输出不相等字符串的差,如果两字符串都相等*str1=*str2会为\0,输出差值为0while ((*str1 == *str2) && (*str1)){str1++;str2++;}return *str1 - *str2;
}

strncpy

        strncpy是长度受限制的字符串拷贝函数,可以指定要拷贝字符的个数,如果源字符串的长度小于要拷贝的个数,就在后边补\0,函数原型如下:

//destination是目标字符串地址,source是源字符串地址,num是要拷贝的字符个数,返回的是目标字符串地址
char * strncpy ( char * destination, const char * source, size_t num );
#include <stdio.h>
#include <string.h>
int main()
{// 代码1char arr[10] = "abcdef";char a[] = "hello";strncpy(arr, a, 3);printf("%s\n", arr);//会打印heldef,只拷贝了三个字符,后面的不变strncpy(arr, a, 5);printf("%s\n", arr);//会打印hellof,只拷贝了五个字符,没有拷贝到\0,后面的不变strncpy(arr, a, 6);printf("%s\n", arr);//会打印hello,拷贝到了\0return 0;
}

strncat

        strncat用于在目标字符串的结尾(第一个\0)处追加源字符串的前num个字符,并且会在后面加上一个\0,其函数原型如下:

//destination是目标字符串地址,source是源字符串地址,num是要追加的字符个数,返回的是目标字符串地址
char * strncat ( char * destination, const char * source, size_t num );

strncmp

        strncmp用来比较两个字符串的前num个字符,其函数原型如下:

//str1是第一个字符串的地址,str2是第二个字符串的地址,num是要比较的字符个数
//如果str1>str2,返回正数,反之返回负数,相等返回0
int strncmp ( const char * str1, const char * str2, size_t num );

strstr

        strstr用于在一个字符串中查找另一个字符串,其函数原型如下:

//在字符串str1中查找字符串str2的位置,如果找到了,返回str2在str1中的起始地址,没找到返回NULL
char * strstr ( const char *str1, const char * str2);
int main()
{char email[] = "abc@godfather.com";char str[] = "godfather";char* ret = strstr(email,str);if(ret == NULL)printf("未找到字符串\n");elseprintf("%s\n",ret);//在email中能找到str,ret会返回g的地址,会打印godfather.comreturn 0;
}

         下面来模拟实现一下strstr:

/** @brief    在字符串str1中查找字符串str2* @param    str1:* @param    str2:* @return   char*: 返回str2在str1中的位置,如果没找到就返回NULL*/
char *my_strstr(const char *str1, const char *str2)
{assert(str1 && str2);const char *s1 = str1;const char *s2 = str2;const char *ret = str1; // ret是str1中向后走的指针while (*ret){s1 = ret;s2 = str2;while (*s1 && *s2 && (*s1 == *s2)) // 如果找到相等的字符就向后查找,如果遇到不相等或某个字符串遇到\0就退出循环{s1++;s2++;}if (*s2 == '\0') // 如果退出循环时s2遇到了\0,就说明找到了字符串,返回此时str1中的起始地址{return (char *)ret;}ret++; // 如果没找到就令str1的移动指针++,向后寻找}return NULL; // 如果遍历完还是没找到就返回NULL
}

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

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

相关文章

ACL的几种类型

ACL&#xff08;Access Control List&#xff0c;访问控制列表&#xff09;主要有以下几种类型&#xff1a; 数字型ACL&#xff1a;这是传统的ACL标识方法&#xff0c;创建ACL时指定一个唯一的数字来标识该ACL。命名型ACL&#xff1a;通过名称代替编号来标识ACL&#xff0c;用…

实战Java虚拟机-高级篇

一、GraalVM 什么是GraalVM GraalVM是Oracle官方推出的一款高性能JDK&#xff0c;使用它享受比OpenJDK或者OracleJDK更好的性能。GraalVM的官方网址&#xff1a;https://www.graalvm.org/官方标语&#xff1a;Build faster, smaller, leaner applications。 更低的CPU、内存…

js实现鼠标拖拽多选功能

实现功能 在PC端的H5页面中&#xff0c;客户拖动鼠标可以连选多个选项 效果展示 具体代码如下 <!DOCTYPE html> <html><head><title>鼠标拖拽多选功能</title><script src"https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js&quo…

ClickHouse配置与使用

静态IP配置 # 修改网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33# 修改文件内容 TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOstatic IPADDR192.168.18.128 NETMASK255.255.255.0 GATEWAY192.168.18.2 DEFROUTEyes IPV4_FAILURE_FATALno IPV6INIT…

《深入解析:近邻算法的原理、实现与应用》

《深入解析&#xff1a;近邻算法的原理、实现与应用》 引言&#xff1a; 在机器学习和数据挖掘领域&#xff0c;近邻算法&#xff08;k-Nearest Neighbors, k-NN&#xff09;是一种基本且常用的分类与回归方法。其核心思想在于根据近邻的信息进行预测&#xff0c;即通过查询输…

Android 屏保开关

设置-显示-屏保&#xff0c; 打开关闭 设置代码在 ./packages/apps/Settings/src/com/android/settings/dream/DreamMainSwitchPreferenceController.java &#xff0c; Overridepublic boolean isChecked() {return mBackend.isEnabled();}Overridepublic boolean setChecke…

【408真题】2009-12

“接”是针对题目进行必要的分析&#xff0c;比较简略&#xff1b; “化”是对题目中所涉及到的知识点进行详细解释&#xff1b; “发”是对此题型的解题套路总结&#xff0c;并结合历年真题或者典型例题进行运用。 涉及到的知识全部来源于王道各科教材&#xff08;2025版&…

招人啦~数通售后、云计算和云服务的岗位需求

小伙伴们大家好&#xff0c;小誉的就业推荐又来咯。想要跳槽晋升找工作的朋友们&#xff0c;千万不要错过机会哦~ 北京集成商数通售后 薪资:12-18k 1、负责公司系统集成项目的网络技术实施工作&#xff0c;包括项目的网络架构的规划、设计、调整、性能优化; 2、负责从项目开展…

零基础HTML教程(35)--网站的本地部署

文章目录 1. 背景2. 网站的本地部署3. 本地部署的步骤4. 服务器软件介绍5. 本地部署实操5.1 开发一个网站5.2 下载服务器软件5.3 将网站复制到服务器软件下5.4 启动服务器软件5.5 通过Http协议访问网站 6. 小结 1. 背景 我们之前开发的网页&#xff0c;都是编写完成后&#xf…

Sass预处理器相关知识笔记

什么是Sass **Sass&#xff08;Syntactically Awesome Stylesheets&#xff09;**是一种CSS预处理器&#xff0c;它扩展了CSS的功能&#xff0c;使其更加强大和灵活。Sass允许开发者使用变量、嵌套规则、混合&#xff08;mixins&#xff09;、继承等特性&#xff0c;从而更高效…

Day22:Leetcode:654.最大二叉树 + 617.合并二叉树 + 700.二叉搜索树中的搜索 + 98.验证二叉搜索树

LeetCode&#xff1a;654.最大二叉树 1.思路 解决方案&#xff1a; 单调栈是本题的最优解&#xff0c;这里将单调栈题解本题的一个小视频放在这里 单调栈求解最大二叉树的过程当然这里还有leetcode大佬给的解释&#xff0c;大家可以参考一下&#xff1a; 思路很清晰&#xf…

云渲染的线程数是什么意思?

云渲染线程是指在云渲染过程中&#xff0c;同时处理渲染任务的线程数量。 线程是CPU调度和执行的基本单位&#xff0c;每个线程可以独立执行一系列指令。在云渲染场景中&#xff0c;服务器通常配备有高性能的CPU&#xff0c;这些CPU可能拥有几十甚至上百个物理核心&#xff0c…

python多个list组成的list去重 考虑顺序

在Python中&#xff0c;如果你有多个列表组成的列表&#xff0c;并且你想要去除其中的重复元素&#xff0c;同时考虑顺序&#xff0c;你可以使用functools.total_ordering装饰器来简化代码&#xff0c;并使用set来去重。 下面是一个示例代码&#xff1a; from functools impo…

Vue2基础及其进阶面试(一)

简单版项目初始化 新建一个vue2 官网文档&#xff1a;介绍 — Vue.js 先确保下载了vue的脚手架 npm install -g vue-cli npm install -g vue/cli --force vue -V 创建项目 vue create 自己起个名字 选择自己选择特性 选择&#xff1a; Babel&#xff1a;他可以将我们写…

单向无头链表实现

目录 1. 为什么要有链表&#xff1f; 2. 链表的种类 3. 具体功能实现 &#xff08;1&#xff09;节点结构体定义 &#xff08;2&#xff09;申请节点 &#xff08;3&#xff09;尾插 &#xff08;4&#xff09;尾删 &#xff08;5&#xff09;头插 &#xff08;6&#…

SDUT 链表3

7-3 sdut-C语言实验-链表的结点插入 分数 20 全屏浏览 切换布局 作者 马新娟 单位 山东理工大学 给出一个只有头指针的链表和 n 次操作&#xff0c;每次操作为在链表的第 m 个元素后面插入一个新元素x。若m 大于链表的元素总数则将x放在链表的最后。 输入格式: 多组输入。…

【Python设计模式13】抽象工厂模式

抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供一个接口&#xff0c;用于创建一系列相关或依赖的对象&#xff0c;而无需指定它们具体的类。抽象工厂模式通过对产品类的抽象&#xff0c;使客户端可以使用抽象工厂来创建…

算法和远程编程题

文章目录 2024心得0504 堆/栈/队列用两个栈实现队列 05 哈希BM52 数组中只出现一次的两个数字 2024 牛客网在线编程 心得 大厂会要求&#xff0c;这个其实没有什么用&#xff0c;就是故意为难人&#xff0c;但是要想找一份工作&#xff0c;这个还是只能去遵守规则。面试造火…

go语言之函数基础

1.介绍 函数是基本的代码块&#xff0c;Go是编译型语言&#xff0c;所以函数编写的顺序是无关紧要的&#xff0c;但是我们一般把main&#xff08;&#xff09;函数写在文件的前面&#xff0c;其他函数按照一定的逻辑顺序编写&#xff08;例如函数被调用顺序&#xff09;。 编写…

PHP的多样化执行方式(parallel PHP多线程实现,原生协程实现,多进程实现,ZTS、NTS、TS又是什么)

进程、线程、协程 进程&#xff1a;应用程序的启动实例&#xff0c;运行起的代码叫进程&#xff0c;有独立的内存空间&#xff0c;类比工厂的P个&#xff08;P1单进程&#xff0c;P>1多进程&#xff09;车间。线程&#xff1a;线程是CPU调度的最小单位&#xff0c;是进程内…