【C语言】字符串函数介绍

目录

前言:

1. strlen 函数

函数介绍

strlen 函数的使用

strlen 函数的模拟实现

2. strcpy 函数

函数介绍

strcpy 函数的使用

strcpy 函数的模拟实现

3. strcat 函数

函数介绍

strcat 函数的使用

strcat 函数的模拟实现

4. strcmp 函数

函数介绍

strcmp 函数的使用

strcmp 函数的模拟实现

补充:

5. strncpy 函数

简单使用

6. strncat 函数

简单使用

7. strncmp 函数 

简单使用

8. strstr 函数 

函数介绍

strstr 函数的使用

strstr 函数的模拟实现

9. strtok 函数

函数介绍

strtok 函数的使用

结语


前言:

初学者在做与字符串相关的代码题时,善用字符串函数可能能让你的做题思路更加清晰,事半功倍,所以我们今天来介绍一些常见的字符串函数

(PS:在使用以下字符串函数时都需要包含头文件:#include <string.h>)

1. strlen 函数

函数介绍

size_t strlen ( const char * str );

功能:求字符串长度

  • 该函数返回的是在字符串中 '\0' 前面出现的字符个数,但不包含 '\0'
  • 参数指向的字符串必须要以 '\0' 结束,否则无法计算字符串长度
  • 函数的返回值类型为 size_t,是无符号整数,因此结果一定是大于或等于 0

strlen 函数的使用

#include <stdio.h>
#include <string.h>int main()
{char ch1[] = "abcdef";size_t ret = strlen(ch1);printf("%d\n", ret); // 6return 0;
}

strlen 函数的模拟实现

模拟思路:因为 strlen 函数求字符串长度的原理是以 '\0' 为结束标志来计算字符个数,所以我们得根据这个性质来模拟实现它

方法一:逐个计数求字符个数

size_t mock_strlen(const char* str)
{int count = 0;while (*str != '\0'){count++;str++;}return count;
}

方法二: 两个指针相减求字符个数

size_t mock_strlen(const char* str)
{int count = 0;char* p = str;while (*p != '\0')p++;return p - str;
}

2. strcpy 函数

函数介绍

char * strcpy ( char * destination, const char * source );

功能:拷贝字符串(把源字符串拷贝到目标字符串)

  • 源字符串 source 必须以 '\0' 结束
  • 目标字符串 destination 必须是可修改的,并且空间得足够大,以确保能存放源字符串
  • 要注意函数参数的顺序,目标字符串在前,源字符串在后

strcpy 函数的使用

#include <stdio.h>
#include <string.h>int main()
{char ch1[] = "abcd";char ch2[20] = { 0 };strcpy(ch2, ch1);printf("%s\n", ch2); //abcdreturn 0;
}

strcpy 函数的模拟实现

模拟思路: 创建一个空间足够大的字符数组,把每个字符一一拷贝过来,最后要记得把 '\0' 也拷贝过来

char* mock_strcpy(char* dest, const char* src)
{// 创建一个临时指针记住目标字符串的起始位置char* ret = dest;while (*src != '\0'){*dest = *src;dest++;src++;}return ret;
}

实际上我们还可以再简化这个代码:整合 while 判断和后置++

简化后的模拟函数:

char* mock_strcpy(char* dest, const char* src)
{// 创建一个临时指针记住目标字符串的起始位置char* ret = dest;while (*(dest++) = *(src++)){;}return ret;
}

3. strcat 函数

函数介绍

char * strcat ( char * destination, const char * source );

功能:追加字符串(在一个字符串后追加另一个字符串)

  • 源字符串 source,目标字符串 destination 都必须以 '\0' 结束
  • 目标字符串 destination 必须是可修改的,并且空间得足够大,以确保能容纳下源字符串
  • 要注意函数参数的顺序,目标字符串在前,源字符串在后

strcat 函数的使用

#include <stdio.h>
#include <string.h>int main()
{char ch1[10] = "abc";char ch2[] = "def";strcat(ch1, ch2);printf("%s\n", ch1); //abcdefreturn 0;
}

strcat 函数的模拟实现

 模拟思路:找到目标空间的 '\0' ,在后面把源字符串拷贝进去

char* mock_strcat(char* dest, const char* src)
{char* ret = dest;while (*dest){dest++;}while (*(dest++) = *(src++)){;}return ret;
}

4. strcmp 函数

函数介绍

int strcmp ( const char * str1, const char * str2 );

 功能:比较字符串 str1 和字符串 str2 的大小

  • 如果第一个字符串大于第二个字符串,则返回大于 0 的数字
  • 如果第一个字符串小于第二个字符串,则返回小于 0 的数字
  • 如果第一个字符串等于第二个字符串,则返回 0

(PS:比较两个字符串大小的原理:比较的是两个字符串中对应位置上字符的ASCII码值的大小)

strcmp 函数的使用

#include <stdio.h>
#include <string.h>int main()
{char ch1[] = "abcd";char ch2[] = "abce";// e的ASCII码值大于d的ASCII码值int ret = strcmp(ch1, ch2);if (ret > 0)printf("大于\n");else if (ret < 0)printf("小于\n");elseprintf("等于\n");return 0;
}

strcmp 函数的模拟实现

模拟思路:逐个字符比较大小

int mock_strcmp(const char* str1, const char* str2)
{while (*str1 == *str2){if (*str1 == '\0'){return 0;}str1++;str2++;}if (*str1 > *str2)return 1;elsereturn -1;
}

在上面的代码中我们把返回值固定为 1 跟 -1,我们可以在这里下功夫,再简化一下代码

int mock_strcmp(const char* str1, const char* str2)
{while (*str1 == *str2){if (*str1 == '\0'){return 0;}str1++;str2++;}// 直接用两个字符串相减return *str1 - *str2;
}

补充:

长度不受限制字符串函数和长度受限制字符串函数的区别

学到这里,大家可能会想:当我们在使用拷贝字符串,追加字符串时,想要拷贝或者追加固定字符数,但是上面的函数都是把一整个字符串拷贝和追加,这就是所谓的长度不受限制。下面我们介绍一下长度受限字符串函数 strncpy,strncat,strncmp,它们就能够拷贝、追加、比较固定长度的字符,其他性质跟长度不受限制函数的一样


5. strncpy 函数

char * strncpy ( char * destination, const char * source, size_t num ); //多了一个参数

功能:拷贝前num个字符串 

简单使用

#include <stdio.h>
#include <string.h>int main()
{char ch1[] = "abcd";char ch2[20] = { 0 };strncpy(ch2, ch1, 3);//拷贝前三个字符printf("%s\n", ch2); // abcreturn 0;
}

6. strncat 函数

char * strncat ( char * destination, const char * source, size_t num ); //多了一个参数

功能: 追加前num个字符串

简单使用

#include <stdio.h>
#include <string.h>int main()
{char ch1[10] = "abc";char ch2[] = "def";strncat(ch1, ch2, 1);//追加1个字符printf("%s\n", ch1); //abcdreturn 0;
}

7. strncmp 函数 

int strncmp ( const char * str1, const char * str2, size_t num ); //多了一个参数

功能:比较 str1 和 str2 前num个字符的大小 

简单使用

#include <stdio.h>
#include <string.h>int main()
{char ch1[] = "abcd";char ch2[] = "abce";int ret = strncmp(ch1, ch2, 3); //两字符串的前3个字符一致if (ret > 0)printf("大于\n");else if (ret < 0)printf("小于\n");elseprintf("等于\n");return 0;
}

8. strstr 函数 

函数介绍

char * strstr ( const char * str1, const char * str2 );

功能:在字符串 str1 中找字符串 str2,如果找到,函数就返回字符串 str2 在字符串 str1 中第一次出现的位置;如果没找到,函数就返回空指针 NULL

strstr 函数的使用

#include <stdio.h>
#include <string.h>int main()
{char str[] = "abcefab";char* p;p = strstr(str, "ce");//返回的是第一次出现的位置printf("%s\n", p); // cefab return 0;
}

strstr 函数的模拟实现

模拟思路:尽量把所有情况一一列举出来,下面是我列举的三种情况

   

我们需要创建三个临时字符指针变量:cur 保存 str1 的起始位置,s1 保存 cur 的起始位置,s2保存 str2 的起始位置。

char* mock_strstr(const char* str1, const char* str2)
{const char* cur = str1;const char* s1 = NULL;const char* s2 = NULL;// 当str2为空指针时,直接返回str1if (*str2 == '\0'){return (char*)str1;}// 开始逐个遍历curwhile (*cur){// 用s1来保存cur的起始位置,慢慢++遍历s1 = cur;s2 = str2;// 相等则继续++while (*s1 == *s2){s1++;s2++;}// 直到遍历完s2确定找到完整字符串,这时返回cur的位置if (*s2 == '\0'){return (char*)cur;}// 没找到就++继续往后寻找cur++;}// 遍历完str1后都没找到,就返回空指针NULLreturn NULL;
}

9. strtok 函数

函数介绍

char * strtok ( char * str, const char * delimiters );

功能:把字符串根据标记拆分开来

  • delimiters 参数定义了用作分隔符的字符集合
  • 字符串 str 中包含了 0  个或多个由 delimiters 字符串中一个或者多个分隔符分割的标记
  • strtok 函数会在 str 中找到标记,并将其以 '\0' 结尾
  • strtok 函数的第一个参数不为 NULL,函数就会在 str 中找到第一个标记,并将保存它在字符串中的位置
  • strtok 函数的第一个参数为 NULL,函数就将在同一个字符串中被保存的位置开始,查找下一个标记
  • 如果字符串中不存在更多的标记,就返回 NULL 指针

PS:因为 strtok 函数在分解的过程中会改变被操作的字符串,所以最好先拷贝一份

上面的解释可能有点绕,我们可以看一个例子来加深理解(实在不懂原理知道怎么用也行)

strtok 函数的使用

#include <stdio.h>
#include <string.h>int main()
{char ch[] = "flmz@163.com";char str[20] = { 0 };// 因为 strtok 函数在分解的过程中会改变被操作的字符串,所以最好拷贝一份strcpy(str, ch);// 标记符const char* p = "@.";char* s = NULL;for (s = strtok(str, p); s != NULL; s = strtok(NULL, p)){printf("%s\n", s);}return 0;
}

结语

今天我们一起学习了字符串函数,包括函数的使用和以及简单地模拟实现;如有总结不到位的地方还请多多谅解,若有出现纰漏,希望大佬们看到错误之后能够在私信或评论区指正,博主会及时改正,共同进步!
欢迎各位在评论区友好讨论。如果觉得不错的话,麻烦您点个赞吧,十分感谢!

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

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

相关文章

前端工程化之:webpack1-12(常用扩展)

目录 前言 一、CleanWebpackPlugin 二、HtmlWebpackPlugin 三、CopyPlugin 四、webpack-dev-server 五 、file-loader 六、url-loader 七、路径问题 前言 由于 webpack 、 webpack-cli 、 webpack-dev-server 会存在版本不兼容问题&#xff0c;所以这里使用的版本如下&…

4K Video Downloader forMac/win:畅享高清视频下载的终极利器!

在如今的数字时代&#xff0c;高清视频已经成为人们生活中不可或缺的一部分。无论是观看精彩的电影、音乐视频&#xff0c;还是学习教育类的在线课程&#xff0c;我们都希望能够以最清晰流畅的方式来欣赏。而为了满足这一需求&#xff0c;我们需要一款功能强大的高清视频下载软…

工业平板电脑定制_三防平板电脑安卓主板厂家

工业平板电脑具有IP68级三防品质&#xff0c;采用高强度工业材质制造&#xff0c;结构稳固坚韧&#xff0c;具备较高的抗冲击和防震能力。隔空减震技术进一步加强了产品的抗冲击和防震动功能。广泛应用于工控、医疗、电信、电力、工业自动化设备、汽车检测、制造业等多个领域&a…

Flink实时数仓同步:快照表实战详解

一、背景 在大数据领域&#xff0c;初始阶段业务数据通常被存储于关系型数据库&#xff0c;如MySQL。然而&#xff0c;为满足日常分析和报表等需求&#xff0c;大数据平台采用多种同步方式&#xff0c;以适应这些业务数据的不同存储需求。这些同步存储方式包括离线仓库和实时仓…

MySQL语句 |条件语句 IFNULL 和 COALESCE 的区别

在MySQL中&#xff0c;IFNULL和COALESCE都是用来处理NULL值的函数&#xff0c;但它们之间存在一些重要的差异。 函数定义 IFNULL(expr1, expr2): 如果expr1为NULL&#xff0c;则返回expr2&#xff0c;否则返回expr1。COALESCE(value1, value2, ..., valueN): 返回参数列表中的…

机器人中的数值优化进阶|【三】三次样条曲线推导(下)

机器人中的数值优化进阶|【三】三次样条曲线推导&#xff08;下&#xff09; 接之前的内容&#xff0c;现在开始考虑势场函数 P ( η 1 , . . . , η n − 1 ) 1000 ∑ i 1 n − 1 ∑ j 0 m max ⁡ ( r j − ∣ ∣ η i − o j ∣ ∣ , 0 ) P(\eta_1,...,\eta_{n-1}) 100…

C语言入门到精通之练习35:打印出杨辉三角形(要求打印出10行)

题目&#xff1a;打印出杨辉三角形&#xff08;要求打印出10行&#xff09;。 程序分析&#xff1a; 结构如下图所示&#xff1a; 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1代码如下&#xff1a; // Created by www.erdangjiade.com 15/11/9. //#incl…

学习方法分享

工作上的代码实现&#xff0c;不要过度设计&#xff0c;不要想着炫技&#xff0c;要简单务实&#xff0c;“大道至简”。 学习一个方向&#xff08;模块化&#xff09;的知识&#xff0c;不经意间就会涉及到另一个领域&#xff0c;比如从消息队列存储的顺序读/写&#xff0c;延…

计算机网络作业答案(ip地址划分,滑动窗口,距离向量算法)

做一个计算机网络作业答案的存档 6.某单位申请到了一个B类IP地址&#xff0c;其网络标识为130.53&#xff0c;现进行子网划分&#xff0c;若选用的子网掩码为 255.255.224.0&#xff0c;请问:(1&#xff09;可划分为多少个子网?(2)每个子网中的主机数最多为多少台?(3&#…

MySQL数据库入门

MySQL数据库概述 1&#xff0c;为什么要使用数据库2&#xff0c;数据库的相关概念3&#xff0c;常见的数据库管理系统4&#xff0c;MySQL介绍5&#xff0c;关系型数据库和非关系型数据库6&#xff0c;关系型数据库的设计规则7&#xff0c;表的关联关系7.1&#xff0c;一对一7.2…

ubuntu server 22.04.3 配置 wifi

1. 配置 wifi 1.1. 查看系统中的网卡 ls /sys/class/net/ $ ls /sys/class/net/ enp1s0 lo wlo1 1.2. 配置 wifi 1.2.1 一个普通的配置 加入我们的机器可能会链接多个网络中的某一个&#xff1a; 网络热点1&#xff1a;ChinaNet-zNpQ password: 12345…

面试高频知识点:2线程 2.1.4 线程池常用参数

1. 核心池大小&#xff08;Core Pool Size&#xff09; 核心池大小是线程池中始终保持存活的线程数量。当有新的任务提交时&#xff0c;线程池会优先使用核心池中的线程来处理任务。这个参数的合理设置直接影响着线程池的性能。如果设置太小&#xff0c;可能导致无法及时处理任…

短剧小程序开发:打造高效、便捷的娱乐体验

随着移动互联网的普及和用户需求的多样化&#xff0c;短剧小程序作为一种新型的应用形态&#xff0c;逐渐受到了广大用户的青睐。短剧小程序开发旨在为用户提供一种高效、便捷的娱乐体验&#xff0c;让用户在忙碌的生活中轻松享受到精彩的短剧内容。本文将探讨短剧小程序开发的…

0203-2-输入输出系统

第六章&#xff1a;输入输出系统 I/O系统的功能&#xff0c;模型和接口 I/O系统管理的对象是I/O设备和相应的设备控制器。 I/O系统的基本功能 隐藏物理设备的细节与设备的无关性提高处理机和I/O设备的利用率对I/O设备进行控制确保对设备的正确共享错误处理 I/O软件的层次结…

Vite与Webpack打包内存溢出问题优雅处理方式

Vite与Webpack打包内存溢出问题处理 文章目录 Vite与Webpack打包内存溢出问题处理1. Vite1. 打包错误提示2. 命令行方式解决3. 配置环境变量方式解决1. 设置变量2. 配置系统的环境变量 2. Webpack1. 打包错误提示2. 命令行方式解决3. 配置环境变量方式解决1. 设置变量2. 配置系…

【DDD】学习笔记-什么是模型

从领域驱动的战略设计进入战术设计&#xff0c;简单说来&#xff0c;就是跨过系统视角的限界上下文边界进入它的内部&#xff0c;从分层架构的逻辑分层进入到每一层的内部。在思考内部的设计细节时&#xff0c;首先需要思考的问题就是&#xff1a;什么是模型&#xff08;Model&…

NETX90-多协议通讯芯片

随着作为信息物理系统核心技术的工业物联网的发展&#xff0c;Hilscher 基于 netX 51/52成功开发了新一代网络控制器netX90&#xff0c;其安全性是产品的核心价值。可实现更高性能的集成&#xff0c;并提高功率效率等级&#xff0c;凭借其较小的外形尺寸能够满足规格尺寸更小的…

C++ 实现单例模式

单例模式 单例模式确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 创建单一实例 怎么让某个类只能创建一个实例&#xff1f; 思路&#xff1a;将类的构造函数私有&#xff0c;然后提供一个静态方法访问对象。调用类内成员函数需要对象&#xff0c;但我们又无法…

css新手教程

css新手教程 课程&#xff1a;14、盒子模型及边框使用_哔哩哔哩_bilibili 一.什么是CSS 1.什么是CSS Cascading Style Sheet 层叠样式表。 CSS&#xff1a;表现&#xff08;美化网页&#xff09; 字体&#xff0c;颜色&#xff0c;边距&#xff0c;高度&#xff0c;宽度&am…