【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…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...

使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...