【C语言】字符串函数
文章目录
- 一、求字符串长度
- strlen
- 例子
- 模拟实现
- 二、长度不受限制的字符串函数
- strcpy
- 例子
- 模拟实现
- strcat
- 例子
- 模拟实现
- strcmp
- 例子
- 模拟实现
- 三、长度受限制的字符串函数
- strncpy
- 例子
- strncat
- 例子
- strncmp
- 例子
- 四、字符串查找
- strstr
- 例子
- 模拟实现
- strtok
- 例子
- 五、错误信息报告
- strerror
- 例子
- 六、字符分类函数
- 七、内存操作函数
- memcpy
- 例子
- 模拟实现
- memmove
- 例子
- 模拟实现
- memcmp
- 例子
一、求字符串长度
strlen

- 功能:获取字符串长度
- 参数:c字符串(str)
- 返回值:字符串长度(无符号整形size_t)
- 字符串将 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
例子
#include <stdio.h>
#include <string.h>
int main()
{const char* str1 = "abcdef";const char* str2 = "bbb";printf("%d\n", strlen(str1));printf("%d\n", strlen(str2));if (strlen(str2) - strlen(str1) > 0){printf("str2>str1\n");}else{printf("srt1>str2\n");}return 0;
}

模拟实现
- 计数器方式
int my_strlen(char* str)
{int len = 0;while (*str){str++;len++;}return len;
}
- 不创建临时变量
int my_strlen(const char* str)
{if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}
- 指针-指针
int my_strlen(char* s)
{char* p = s;while (*p!='\0'){p++;}return p - s;
}
二、长度不受限制的字符串函数
strcpy

- 功能:复制字符串
- 参数:目的字符串(destination)源字符串(source)
- 返回值:目的字符串
- 源字符串必须以 ‘\0’ 结束
- 会将源字符串中的 ‘\0’ 拷贝到目标空间
- 目标空间必须足够大,以确保能存放源字符串
- 目标空间必须可变
例子
#include <stdio.h>
#include <string.h>int main()
{char str1[] = "Sample string";char str2[40];char str3[40];strcpy(str2, str1);strcpy(str3, "copy successful");printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3);return 0;
}

模拟实现
char* my_strcpy(char* dest, const char* src)
{char* ret = dest;//assert需要加入头文件assert.hassert(src != NULL);assert(dest != NULL);while (*dest++=*src++){}return ret;
}
strcat

- 功能:连接字符串
- 参数:目的字符串(destination)源字符串(source)
- 返回值:目的字符串
- 将源字符串的副本追加到目标字符串。目标中的终止空字符被源的第一个字符覆盖,并且在目标中由两者串联形成的新字符串的末尾包含一个空字符。
- 目的地和来源不得重叠。
例子
#include <stdio.h>
#include <string.h>int main ()
{char str[80];strcpy (str,"these ");strcat (str,"strings ");strcat (str,"are ");strcat (str,"concatenated.");puts (str);return 0;
}

模拟实现
char* my_strcat(char* dest, const char* src)
{char* ret = dest;//assert需要加入头文件assert.hassert(dest);assert(src);while (*dest){dest++;}while (*dest++ = *src++){}return ret;
}
strcmp

- 功能:比较两个字符串
- 参数:要比较的字符串1(str1)要比较的字符串2(str2)
- 返回值:
| 返回值 | 表明 |
|---|---|
| <0 | 第一个不匹配的字符在 PTR1 中的值低于 PTR2 中的值 |
| 0 | 两个字符串的内容相等 |
| >0 | 第一个不匹配的字符在 PTR1 中的值大于在 PTR2 中的值 |
- 此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续下一对,直到字符不同或达到终止空字符
例子
#include <stdio.h>
#include <string.h>int main()
{int ret = strcmp("bbq", "bcq");if (ret > 0)printf(">\n");printf("%d\n", ret);return 0;
}

模拟实现
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);
}
三、长度受限制的字符串函数
strncpy

- 功能:从字符串中复制字符
- 参数:目的字符串(destination)源字符串(source)要从源中复制的最大字符数(num)
- 返回值:目的字符串
- 拷贝num个字符从源字符串到目标空间
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
- 如果源长度超过 num,则不会在目标末尾隐式附加空字符。因此,在这种情况下,不应将目标视为以空结尾的 C 字符串(这样读取它会溢出)
- 目的地和来源不得重叠
例子
#include <stdio.h>
#include <string.h>int main()
{char str1[] = "To be or not to be";char str2[40];char str3[40];strncpy(str2, str1, sizeof(str2));strncpy(str3, str2, 5);str3[5] = '\0'; puts(str1);puts(str2);puts(str3);return 0;
}

strncat

- 功能:从字符串追加字符
- 参数:目的字符串(destination)源字符串(source)要追加的最大字符数(num)
- 返回值:目的字符串
- 将源的第一个数字字符追加到目标,外加一个终止空字符
- 如果源中 C 字符串的长度小于 num,则仅复制终止空字符之前的内容
- 目标空间必须足够大以包含串联的结果字符串,包括其他 null 字符
例子
#include <stdio.h>
#include <string.h>int main()
{char str1[20];char str2[20];strcpy(str1, "To be ");strcpy(str2, "or not to be");strncat(str1, str2, 6);puts(str1);return 0;
}

strncmp

- 功能:比较两个字符串的字符
- 参数:要比较的字符串1(str1)要比较的字符串2(str2)要比较i的最大字符数(num)
- 返回值:
| 返回值 | 表明 |
|---|---|
| <0 | 不匹配的第一个字符在 str1 中的值低于 str2 中的值 |
| 0 | 两个字符串的内容相等 |
| >0 | 第一个不匹配的字符在 str1 中的值大于在 str2 中的值 |
- 将 C 字符串 str1 的字符数与 C 字符串 str2 的字符数进行比较
- 此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用以下对,直到字符不同,直到达到终止的空字符,或者直到两个字符串中的 num 字符匹配,以先发生者为准
例子
#include <stdio.h>
#include <string.h>int main()
{char str[][5] = { "R2D2" , "C3PO" , "R2A6" };int n;puts("Looking for R2 astromech droids...");for (n = 0; n < 3; n++)if (strncmp(str[n], "R2xx", 2) == 0){printf("found %s\n", str[n]);}return 0;
}

四、字符串查找
strstr

- 功能:查找子字符串
- 参数:要扫描的字符串(str1)包含要匹配的字符序列的字符串(str2)
- 返回值:指向 str1 中指定的整个字符序列在 str2 中首次出现的指针,如果序列在 str1 中不存在,则为 null 指针
例子
#include <stdio.h>
#include <string.h>int main()
{char str[] = "This is a simple string";char* pch;pch = strstr(str, "simple");if (pch != NULL)strncpy(pch, "sample", 6);puts(str);return 0;
}

模拟实现
char* my_strstr(const char* str1, const char* str2)
{char* cp=str1;char* s1=str1;char* s2=str2;if (*str2 == '\0')return str1;while (*cp){s1 = cp;s2 = str2;while (*s1 && *s2 && *s1 == *s2){s1++;s2++;}if (*s2 == '\0')return cp;cp++;}return NULL;
}
strtok

- 功能:将字符串拆分为标记
- 参数:要截断的c字符串(str)包含分割字符的c字符串(delimiters)
- 返回值:如果找到令牌,则指向令牌开头的指针,否则为空指针。当在正在扫描的字符串中到达字符串的末尾(即空字符)时,始终返回空指针
- strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改)
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记
例子
#include <stdio.h>
#include <string.h>int main ()
{char str[] ="- This, a sample string.";char * pch;printf ("Splitting string \"%s\" into tokens:\n",str);pch = strtok (str," ,.-");while (pch != NULL){printf ("%s\n",pch);pch = strtok (NULL, " ,.-");}return 0;
}

五、错误信息报告
strerror

- 功能:获取指向错误消息字符串的指针
- 参数:错误号(errnum)
- 返回值:指向描述错误错误的字符串的指针
- 解释 errnum 的值,生成一个字符串,其中包含描述错误条件的消息,就像由库的函数设置为 errno 一样
例子
#include <stdio.h>
#include <string.h>
int main()
{int i = 0;for (i = 0; i < 10; i++){printf("%d: %s\n", i, strerror(i));}return 0;
}

六、字符分类函数
| 函数 | 如果他的参数符合下列条件就返回真 |
|---|---|
| iscntrl | 任何控制字符 |
| isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
| isdigit | 十进制数字 0~9 |
| isxdigit | 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A ~F |
| islower | 小写字母a~z |
| isupper | 大写字母A~Z |
| isalpha | 字母a~ z或A~Z |
| isalnum | 字母或者数字,a ~ z,A~ Z,0~9 |
| ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
| sgraph | 任何图形字符 |
| isprint | 任何可打印字符,包括图形字符和空白字符 |
七、内存操作函数
memcpy

- 功能:复制内存块
- 参数:指向目标数组的指针(destinatiom)指向要复制的数据源的指针(source)要复制的字节数(num)
- 返回值:返回目标
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置
- 这个函数在遇到 ‘\0’ 的时候并不会停下来
- 如果source和destination有任何的重叠,复制的结果都是未定义的
例子
#include <stdio.h>
#include <string.h>int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };//将arr1中的内容,拷贝到arr2中memcpy(arr2, arr1, 40); int i = 0;for (i = 0; i < 20; i++){printf("%d ", arr2[i]);}return 0;
}

模拟实现
void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest && src);while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}
memmove

- 功能:移动内存块
- 参数:指向目标数组的指针(destinatiom)指向要复制的数据源的指针(source)要复制的字节数(num)
- 返回值:返回目标
- 将字节数的值从源指向的位置复制到目标指向的内存块。复制就像使用了中间缓冲区一样,允许目标和源重叠
- 该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数
例子
#include <stdio.h>
#include <string.h>
int main()
{char str[] = "memmove can be very useful......";memmove(str + 20, str + 15, 11);puts(str);return 0;
}

模拟实现
void* my_memmove(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest && src);if (dest < src){while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}
memcmp

- 功能:比较两个内存块
- 参数:指向内存块的指针1(str1)指向内存块的指针2(str2)要比较的字节数(num)
- 返回值:
| 返回值 | 表明 |
|---|---|
| <0 | 两个内存块中不匹配的第一个字节在 PTR1 中的值低于 PTR2 中的值 |
| 0 | 两个内存块的内容相等 |
| >0 | 两个内存块中不匹配的第一个字节在 PTR1 中的值大于在 PTR2 中的值 |
- 与 strcmp 不同,该函数在找到空字符后不会停止比较
例子
#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,1,4,5,6 };int arr2[] = { 1,2,33 };int ret = memcmp(arr1, arr2, 10);printf("%d\n", ret);return 0;
}


相关文章:
【C语言】字符串函数
文章目录 一、求字符串长度strlen例子模拟实现 二、长度不受限制的字符串函数strcpy例子模拟实现 strcat例子模拟实现 strcmp例子模拟实现 三、长度受限制的字符串函数strncpy例子 strncat例子 strncmp例子 四、字符串查找strstr例子模拟实现 strtok例子 五、错误信息报告strer…...
【数据挖掘】时间序列教程【九】
第5章 状态空间模型和卡尔曼滤波 状态空间模型通常试图描述具有两个特征的现象 有一个底层系统具有时变的动态关系,因此系统在时间上的“状态”t 与系统在时间的状态t−1有关 .如果我们知道系统在时间上的状态t−1 ,那么我们就有了我们需要知道的一切&am…...
数据结构---特殊矩阵和广义表
🌞欢迎来到机器学习的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 🙏作者水平很有限,如果发现错误ÿ…...
mysql数据库的定时备份脚本(docker环境和非docker环境)
一、非docker安装的MySQL MySQL作为一种常用的数据库管理系统,拥有着众多的优秀特性,如高性能、高可靠性、高可扩展性等。然而,在数据备份上,也需要我们进行一定的处理,这样才能保证数据的安全性。因此,在这里我们将介绍如何定时备份MySQL数据库。 我们可以通过MySQL自…...
【微信小程序】使用 wx.request 方法进行异步网络请求
在微信小程序中,你可以使用 wx.request 方法进行异步网络请求,并将获取到的列表数据渲染到 UI 上。 首先,在页面的 data 中定义一个数组变量,用于存储获取到的列表数据,例如: Page({data: {listData: [] …...
MySQL 8 修改root密码ERROR 1064 (42000): You have an error in your SQL syntax;
root先利用原密码登陆 mysql -u root -p Enter password: ******* Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 8.0.26 MySQL Community Server - GPLCopyright (c) 2000, 2021, Oracle and/or its affiliate…...
SpringCloud——分布式请求链路跟踪Sleuth
安装运行zipkin SpringCloud从F版已不需要自己构建Zipkin Server,只需要调用jar包即可 https://dl.bintray.com/oenzipkin/maven/io/zipkin/java/zipkin-server/ 下载:zipkin-server-2.12.9-exec.jar 运行:java -jar zipkin-server-2.12.9-e…...
【2 beego学习 - 项目导入与项目知识点】
0 项目导入 1 在英文路径下新建一个同名的项目,拷贝其他数据到这个文件 bee new 同名项目名 cd 同名项目名 go mod tidy go get -u -v github.com/astaxie/beego go get 同名项目名/models2 拷贝部分的项目文件到新目录 bee run 运行的其他错误,按照提示安装文件 1 后端获取…...
Langchain-ChatGLM配置文件参数测试
1 已知可能影响对话效果的参数(位于configs/model_config.py文件): # 文本分句长度 SENTENCE_SIZE 100# 匹配后单段上下文长度 CHUNK_SIZE 250 # 传入LLM的历史记录长度 LLM_HISTORY_LEN 3 # 知识库检索时返回的匹配内容条数 VECTO…...
测试QT读写锁(QReadWriteLock )和互斥锁(QReadWriteLock )的执行效率
上代码: #include <QCoreApplication> #include <QElapsedTimer> #include <QtConcurrent> #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);qSetMessagePattern("(%{time hh:mm:ss.zzz} %{thre…...
如何在 Windows 中免费合并 PDF 文件 [在线和离线]
PDF是一种广泛使用的文件格式,具有兼容性好、安全性高、易于打印、方便浏览等众多优点。在工作和学习过程中,经常需要将同一类型的PDF文件合并起来,以方便传输和查看,使得合并PDF文件成为一种重要的数据整合方法。 如果您想知道如…...
【LLM】金融大模型场景和大模型Lora微调实战
文章目录 一、金融大模型背景二、大模型的研究问题三、大模型技术路线四、LLaMA家族模型五、Lora模型微调的原理六、大模型Lora微调实战Reference 一、金融大模型背景 金融行业需要垂直领域LLM,因为存在金融安全和数据大多数存储在本地,在风控、精度、实…...
途乐证券股市资讯-英伟达,又创历史新高!美股全线上涨
当地时间13日,美股三大股指集体收涨,纳指、标普500指数双双改写2022年4月以来的新高。到收盘,道指涨0.14%,报34395.14点;纳指涨1.58%,报14138.57点;标普500指数涨0.85%,报4510.04点。…...
MySQL表聚合函数
前言 哈喽,各位小伙伴大家好,本篇文章为大家介绍几个MySQL中常用的聚合函数,什么是聚合函数,相信第一次看到这个名词的小伙伴是比较懵的,举个例子,比如说统计表中数据的个数,就可以使用MySQL中提…...
JavaWeb 速通XML
目录 一、XML快速入门 1.基本介绍 : 2.入门案例 : 二、XML语法 0.文件结构 : 1.文档声明 : 2. 元素 : 3.属性 : 4.注释 : 5.CDATA节 : PS : XML转义符 : 三、Dom4j 1.关于XML解析技术 : 2 Dom4j介绍 : 3.Dom4j使用 : 1 获取Document对象的三种方式 2 …...
redis浅析
一 什么是NoSQL? Nosql not only sql(不仅仅是SQL) 关系型数据库:列行,同一个表下数据的结构是一样的。 非关系型数据库:数据存储没有固定的格式,并且可以进行横向扩展。 NoSQL泛指非关系…...
四种缓存的避坑总结
背景 分布式、缓存、异步和多线程被称为互联网开发的四大法宝。今天我总结一下项目开发中常接触的四种缓存实际项目中遇到过的问题。 JVM堆内缓存 JVM堆内缓存因为可以避免memcache、redis等集中式缓存网络通信故障问题,目前还在项目中广泛使用。 堆内缓存需要注…...
flutter开发实战-flutter二维码条形码扫一扫功能实现
flutter开发实战-flutter二维码条形码扫一扫功能实现 flutter开发实战-flutter二维码扫一扫功能实现,要使用到摄像头的原生的功能,使用的是插件:scan 效果图如下 一、扫一扫插件scan # 扫一扫scan: ^1.6.01.1 iOS权限设置 <key>NSCa…...
一篇文章了解Redis分布式锁
Redis分布式锁 什么是分布式锁? redis分布式锁是一种基于redis实现的锁机制,它用于在多并发分布式环境下控制并发访问共享资源。在多个应用程序或是进程访问共享资源时,分布式锁可以确保只有一个进程可以访问该资源,不会发生…...
记录第一次组装电脑遇到的坑
京东装机大师配置清单如下: 主板cpu安装 本次安装拆了两次主板 原因1.主板侧面有个金属板需要从内部安装 2.cpu风扇有个板需要装在主板底下 显卡比较大个要最后装,要不然可能要拆好几次 装系统时候 u盘启动认不出来,他妈的是因为机箱上的usb…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...
今日行情明日机会——20250609
上证指数放量上涨,接近3400点,个股涨多跌少。 深证放量上涨,但有个小上影线,相对上证走势更弱。 2025年6月9日涨停股主要行业方向分析(基于最新图片数据) 1. 医药(11家涨停) 代表标…...
