【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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

MySQL数据库入门

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

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

随着移动互联网的普及和用户需求的多样化&#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;凭借其较小的外形尺寸能够满足规格尺寸更小的…

css新手教程

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

Linux信号详解~

目录 前言 一、初识信号 二、信号的概念 三、信号的发送与捕捉 3.1 信号的发送 3.1.1 kill 命令 3.1.2 kill 函数 3.1.3 raise函数 3.1.4 abort函数 3.2 信号的捕捉 3.2.1 signal函数 3.2.2 sigaction函数 3.2.3 图示 四、信号的产生 4.1 硬件异常产生信号 4.2 …

CMake Msys2 搭配vscode

(一)MSYS2介绍 MSYS2&#xff08;Minimal SYStem 2&#xff09;是一个集成了大量的GNU工具链、工具和库的开源软件包集合。它提供了一个类似于Linux的shell环境&#xff0c;可以在Windows系统中编译和运行许多Linux应用程序和工具。 MSYS2基于MinGW-w64平台&#xff0c;提供了…

Linux---进程间通信 | 管道 | PIPE | MKFIFO | 共享内存 | 消息队列

管道 管道是UNIX中最古老的进程间通信的形式&#xff0c;我们把从一个进程连接到另一个进程的数据流称为一个管道。 一个文件&#xff0c;可以被多个进程打开吗&#xff1f;可以&#xff0c;那如果一个进程打开文件&#xff0c;往文件里面写数据&#xff0c;另一个进程打开文…

MySQL 中 int(1) 和 int(10) 会影响存储的长度吗

一、MySQL 中 int(1) 和 int(10) 在MySQL数据库设计中&#xff0c;经常会遇到 int 类型的字段&#xff0c;并会习惯性的指定长度&#xff0c;比如&#xff1a; int(1) 和int(10)&#xff0c;而一些新手可能会误解它们之间的关系&#xff0c;认为 int(10) 能够存储更多的数据。…

Android Camera2 API 后台服务

最近在搞CameraAPP需要将Camera2弄成一个后台服务&#xff0c;发现跟预览的Activity没多大变动只是加了Service&#xff0c;和一些简单的修改。之前的公司也用到Camera2&#xff0c;发现用到的时候还是蛮多的所以记录一下&#xff0c;代码在文章末尾 camera2的结构如下&#x…

Peter算法小课堂—Dijkstra最短路算法

大家好&#xff0c;我们人见人爱、花见花开、车见车爆胎的Peter Pan来啦&#xff0c;hia~hia~hia。今天&#xff0c;我们今天来学习毒瘤的最短路算法啦。啊这……什么是Dijkstra算法&#xff1f;长文警告⚠ 正经点啊 手算样例 大家思考一下&#xff0c;你在手算样例的时候&am…

企业申请sectigo ip https证书

Sectigo&#xff08;原名Comodo&#xff0c;在整合https证书业务后改名为Sectigo&#xff09;是一家知名的数字证书提供商&#xff0c;拥有多种类型的数字证书&#xff0c;例如单域名https证书、多域名https证书、通配符https证书、IP https证书和代码签名证书等满足各类用户的…

2024022期传足14场胜负前瞻

2024022期赛事由英超4场&#xff0c;德甲2场、意甲4场、西甲4场组成。售止时间为2月4日&#xff08;周日&#xff09;19点00分&#xff0c;敬请留意&#xff1a; 本期中深盘较多&#xff0c;1.5以下赔率3场&#xff0c;1.5-2.0赔率7场&#xff0c;其他场次是平半盘、平盘。本期…

TCP 协议的相关特性

1. TCP格式 TCP特性&#xff1a;有连接&#xff0c;全双关&#xff0c;面向字节流&#xff0c;可靠传输。&#xff08;TCP安身立命的本钱&#xff0c;初心就是解决“可靠传输”问题&#xff09; 其实TCP的特征有很多这里我就简单的介绍几个。 2. 确认应答 其实用来确保可靠性&…