深入解析:C语言字符串安全查找 :strchr_s、strrchr_s、strstr_s

news/2025/11/5 15:02:56/文章来源:https://www.cnblogs.com/slgkaifa/p/19193671

深入解析:C语言字符串安全查找 :strchr_s、strrchr_s、strstr_s

在 C11 标准中,为了增强字符串操作的安全性,引入了一系列安全版本的字符串函数。下面详细解析 strchr_sstrrchr_sstrstr_s 这三个字符串安全查找函数。

1. strchr_s - 安全字符查找

函数原型

errno_t strchr_s(
const char *str,
size_t strsz,
int ch,
char **result
);

功能说明

查找字符 ch 在字符串 str 中第一次出现的位置。

参数说明

返回值

  • 成功:返回 0
  • 失败:返回非零错误码

示例代码

#include <stdio.h>#include <string.h>int main() {const char *text = "Hello, World!";char *result = NULL;errno_t err;// 查找字符 'W'err = strchr_s(text, strlen(text) + 1, 'W', &result);if (err == 0 && result != NULL) {printf("找到字符 'W',位置:%ld\n", result - text);printf("剩余字符串:%s\n", result);} else {printf("未找到字符 'W'\n");}return 0;}

2. strrchr_s - 安全反向字符查找

函数原型

errno_t strrchr_s(
const char *str,
size_t strsz,
int ch,
char **result
);

功能说明

查找字符 ch 在字符串 str 中最后一次出现的位置。

示例代码

#include <stdio.h>#include <string.h>int main() {const char *filename = "document.txt.backup";char *result = NULL;errno_t err;// 查找最后一个点号err = strrchr_s(filename, strlen(filename) + 1, '.', &result);if (err == 0 && result != NULL) {printf("文件扩展名:%s\n", result + 1); // 跳过点号} else {printf("未找到文件扩展名\n");}return 0;}

3. strstr_s - 安全子串查找

函数原型

errno_t strstr_s(
const char *str,
size_t strsz,
const char *substr,
char **result
);

功能说明

查找子串 substr 在字符串 str 中第一次出现的位置。

示例代码

#include <stdio.h>#include <string.h>int main() {const char *text = "The quick brown fox jumps over the lazy dog";char *result = NULL;errno_t err;// 查找子串 "fox"err = strstr_s(text, strlen(text) + 1, "fox", &result);if (err == 0 && result != NULL) {printf("找到子串 'fox',位置:%ld\n", result - text);printf("从该位置开始的字符串:%s\n", result);} else {printf("未找到子串 'fox'\n");}return 0;}

4. 完整示例程序

#include <stdio.h>#include <string.h>#include <errno.h>void demonstrate_strchr_s() {printf("=== strchr_s 示例 ===\n");const char *text = "Programming in C";char *result = NULL;errno_t err = strchr_s(text, strlen(text) + 1, 'g', &result);if (err == 0 && result != NULL) {printf("第一个 'g' 在位置:%ld\n", result - text);} else {printf("查找失败,错误码:%d\n", err);}}void demonstrate_strrchr_s() {printf("\n=== strrchr_s 示例 ===\n");const char *path = "/home/user/documents/file.txt";char *result = NULL;errno_t err = strrchr_s(path, strlen(path) + 1, '/', &result);if (err == 0 && result != NULL) {printf("文件名:%s\n", result + 1);} else {printf("查找失败,错误码:%d\n", err);}}void demonstrate_strstr_s() {printf("\n=== strstr_s 示例 ===\n");const char *sentence = "C programming is powerful and C is widely used";char *result = NULL;errno_t err = strstr_s(sentence, strlen(sentence) + 1, "C programming", &result);if (err == 0 && result != NULL) {printf("找到子串,位置:%ld\n", result - sentence);printf("内容:%s\n", result);} else {printf("未找到子串,错误码:%d\n", err);}}int main() {demonstrate_strchr_s();demonstrate_strrchr_s();demonstrate_strstr_s();return 0;}

5. 错误处理

这些函数在发生错误时会返回相应的错误码:

#include <stdio.h>#include <string.h>void error_handling_example() {const char *text = "Hello";char *result = NULL;// 测试各种错误情况// 1. 空指针errno_t err = strchr_s(NULL, 10, 'H', &result);if (err != 0) {printf("错误:空指针,错误码:%d\n", err);}// 2. 字符串长度超过缓冲区大小err = strchr_s(text, 3, 'o', &result); // 实际字符串长度 > 3if (err != 0) {printf("错误:缓冲区大小无效,错误码:%d\n", err);}// 3. 正常情况err = strchr_s(text, strlen(text) + 1, 'l', &result);if (err == 0 && result != NULL) {printf("成功找到字符,位置:%ld\n", result - text);}}

6. 与传统函数的对比

特性传统函数安全版本
参数验证有完整的参数检查
缓冲区溢出保护通过 strsz 参数提供
返回值直接返回指针通过错误码和输出参数
空指针处理未定义行为明确返回错误码

字符串安全查找函数对比表

特性strchr_sstrrchr_sstrstr_s
函数原型errno_t strchr_s(const char *str, size_t strsz, int ch, char **result)errno_t strrchr_s(const char *str, size_t strsz, int ch, char **result)errno_t strstr_s(const char *str, size_t strsz, const char *substr, char **result)
查找方向正向查找(从左到右)反向查找(从右到左)正向查找(从左到右)
查找目标单个字符单个字符字符串(子串)
查找内容字符 ch字符 ch子串 substr
返回位置第一次出现的位置最后一次出现的位置第一次出现的位置
主要用途查找字符首次出现查找字符最后出现查找子串首次出现
典型应用场景解析字符串前缀、查找分隔符文件扩展名提取、路径解析关键词搜索、模式匹配
参数类型int ch(字符)int ch(字符)const char *substr(字符串)
时间复杂度O(n)O(n)O(n×m) 最坏情况
返回值机制通过 result 输出参数返回位置通过 result 输出参数返回位置通过 result 输出参数返回位置
错误返回值非零错误码非零错误码非零错误码

详细功能对比

功能细节strchr_sstrrchr_sstrstr_s
查找范围整个字符串整个字符串整个字符串
匹配方式精确字符匹配精确字符匹配子串完全匹配
空字符处理会找到字符串结束符 \0会找到字符串结束符 \0不会匹配空字符串
大小写敏感
内存安全是(通过strsz参数)是(通过strsz参数)是(通过strsz参数)
标准版本C11C11C11

使用示例对比

使用场景strchr_sstrrchr_sstrstr_s
示例输入"hello@example.com""/path/to/file.txt""C programming is fun"
查找目标'@''/'"programming"
查找结果"@example.com""/file.txt""programming is fun"
实际应用邮箱域名提取文件名提取关键词定位

错误处理对比

错误情况strchr_sstrrchr_sstrstr_s
str为NULL返回错误返回错误返回错误
result为NULL返回错误返回错误返回错误
strsz为0返回错误返回错误返回错误
strsz超过实际大小可能返回错误可能返回错误可能返回错误
未找到目标result设为NULL,返回0result设为NULL,返回0result设为NULL,返回0
substr为NULL不适用不适用返回错误

性能特点对比

性能指标strchr_sstrrchr_sstrstr_s
最佳情况O(1) - 目标在开头O(n) - 必须扫描整个字符串O(n) - 目标在开头
最坏情况O(n) - 目标在末尾或不存在O(n) - 必须扫描整个字符串O(n×m) - 需要回溯匹配
平均情况O(n/2)O(n)O(n+m)
内存访问顺序访问顺序访问(但需要记录最后位置)顺序访问,可能回溯

适用场景总结

场景类型推荐函数理由
查找分隔符strchr_s / strrchr_s单字符查找效率高
提取文件扩展名strrchr_s需要找到最后一个点号
搜索关键词strstr_s需要匹配整个子串
解析路径strrchr_s提取文件名或最后一级目录
验证字符串格式strchr_s检查特定字符是否存在
文本内容搜索strstr_s在长文本中查找短语

这个对比表清晰地展示了三个安全字符串查找函数在功能、性能和适用场景上的差异,帮助开发者根据具体需求选择合适的函数。

总结

安全版本的字符串查找函数提供了以下优势:

  1. 参数验证:检查空指针和无效参数
  2. 边界检查:通过 strsz 参数防止缓冲区溢出
  3. 明确的错误处理:通过返回值提供详细的错误信息
  4. 一致性:统一的错误返回机制

在使用这些函数时,务必:

这些安全函数特别适用于对安全性要求较高的应用程序,如系统软件、网络服务等。

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

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

相关文章

2025年靠谱的连锁泡菜加盟公司排名,泡菜加盟正规公司推荐

2025年餐饮加盟市场持续升温,泡菜品类凭借酸辣开胃的风味、灵活的消费场景,成为创业者青睐的赛道。但行业中加盟品牌鱼龙混杂:部分品牌无核心技术沉淀,产品同质化严重;部分快招公司圈钱跑路,让创业者血本无归;还…

2025年消雾装置冷却塔供货厂家权威推荐:消雾冷却塔/消雾冷却塔选型/消雾冷却塔变频源头厂家精选

随着国家环保政策收紧和工业节水需求提升,消雾装置冷却塔市场年增长率已连续三年超过15%,其中高效节水型产品占据市场份额的45%以上。 消雾装置冷却塔作为工业循环水系统的核心设备,正朝着高效消雾、节能降噪、智能…

深入解析:多模态医疗大模型Python编程合规前置化与智能体持续学习研究(中)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

前端图片压缩三方库browser-image-compression的使用实践

上篇文章是deepseek给出的前端图片压缩方案建议,后经过查看各第三方库的github项目和压缩后相同大小文件的对比,可以得出结论,这几个三方库其实也都是浏览器原生Canvas API的封装.当然,不管它们怎么实现的,只要用起来方…

特氟龙喷涂厂家TOP5推荐:特氟龙喷涂厂家推荐指南

在众多工业防护涂层中,特氟龙喷涂凭借其独特的性能优势,在密封圈、食品模具、化工设备等多个领域广泛应用,市场对优质特氟龙喷涂厂家的需求也日益增长。然而,企业在选择厂家时,常面临诸多困惑,如基础性能不达标、…

网络图片下载+VideCoding+DeepSeekOCR解析实践

网络图片下载+VideCoding+DeepSeekOCR解析实践背景 某高校师资网站全面采用网络图片展示,网站是禁止右键使用下载,也不允许复制信息。我们试图采集这些信息,使用目前智能体任务+VibeCoding+Deepsee-OCR解析来…

如何处理旧 iPhone:安全地回收或重新利用 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

给图片添加水印接口(文字水印和照片水印)

最近在调试的时候,发现打印出来的卡证上姓名处本来应该是中文名的地方,结果出现了三个方框。初步怀疑是再给图片加水印的时候乱码了(原本服务器是Windows的,后面换成Linux)。经过排查,发现代码中有调用Graphics2…

【Android】一种应用霸屏方式:设置固定应用

View Post【Android】一种应用霸屏方式:设置固定应用简介 Android系统中的"固定应用"功能,也常被称为"屏幕固定"或"应用固定",是一项非常实用的屏幕锁定功能。它能够将当前应用锁定在…

测试2网站收藏 - Su

学习 语雀/工作台 软件 Gitee Git教程-廖雪峰 韦东山freeRTOS快速入门 硬件 嘉立创客户中心/PCB.SMT.3D打印等服务 立创商城/元器件 立创开源广场 画PCB必备的3D元器件模型下载地址整理 结构 练习 Learn Git Branching…

2025年密闭冷却塔品牌排名推荐:密闭冷却塔加工厂价格哪家合理

在工业冷却领域,密闭冷却塔作为关键设备,其性能直接影响工艺稳定性、能耗成本与环保合规。面对市场上良莠不齐的供应商,企业如何选择价格合理、质量可靠、服务完善的合作伙伴?以下结合技术实力、市场口碑与行业适配…

Apache SeaTunnel 支持 Metalake 开发了!避免任务配置敏感信息暴露

在2025年开源之夏活动中,我参与了Apache SeaTunnel项目的开发,目标是解决任务配置中敏感信息暴露的问题。今年的开源之夏活动已接近尾声,Apache SeaTunnel 社区的开发者们在经过漫长的开发过程也都收获了自己的成果…

2025年深圳巨量竞价开户公司权威推荐榜单:爱采购开户/爱采购运营/巨量推广源头公司精选

在数字化营销浪潮的推动下,深圳作为科技与创新前沿阵地,企业对巨量引擎平台的专业投放需求正持续攀升。根据行业统计,2025年抖音电商GMV已突破2.5万亿元,平台月活超7.8亿,流量红利显著,但规则升级速度同样惊人,…

System Exec.vi

System Exec.viLabVIEW 的 System Exec.vi 是一个非常常用的系统调用节点,用于在 VI 中执行 外部命令或程序(exe、bat、cmd、python等)。 下面是详细讲解与示例:🧩 一、System Exec.vi 功能说明 路径:Functions…

HR内耗终结者:Moka People实现招聘、人事、薪酬全流程数据一体化,提效200%

对于奋战在一线的HRBP或SSC(共享服务中心)成员而言,效率的瓶颈往往不在于工作量大,而在于流程的碎片化和数据的重复操作。每月的薪酬核对、跨系统的入职信息录入、复杂的考勤数据导入,这些低价值的事务性工作不仅…

每周读书与学习-JMeter主要元件详细介绍(四)再谈取样器

每周读书与学习是由清华大学出版社出版的《JMeter核心技术、性能测试与性能分析》一书的作者推出,分享作者多年的IT从业经历,希望对很多计算机科学技术IT类专业毕业生以及IT从业者有所帮助。 1、取样器 在前面的章节…

2025年济南靠谱龙工叉车公司推荐,专业龙工叉车平台全解析

叉车作为工业物流的核心设备,其选型、运维与管理直接影响企业的生产效率与运营成本。在济南及周边地区,龙工叉车凭借高性价比、稳定性能占据重要市场份额,但面对众多龙工叉车服务机构,如何选择专业靠谱的合作伙伴?…

AI|AI优化企业新榜单与选择指南 - 二当家

AI优化企业新势力:解码流量增长新引擎 2025年AI优化企业TOP3:东晟领跑,技术驱动全域增长 头部企业实力对决:从技术壁垒到场景深耕 在生成式AI重构搜索生态的2025年,企业流量获取逻辑已从“关键词堆砌”转向“场景…

多存储文件列表神器Alist:轻松管理你的云端资源

Alist是一个支持多种存储服务的文件列表程序,使用Gin和Solidjs构建,能够将多个网盘和存储服务聚合在一个界面中统一管理,支持WebDAV等多种协议,让你的文件管理更加高效便捷。Alist - 多存储文件列表程序:card_inde…

电阻作用

以下是一套快速且合理的方法,帮助你像专家一样判断这些电阻的作用。 核心分析框架:问自己五个关键问题 看到一个电阻,依次问下面这些问题,八成以上的电阻作用都能被快速定位。它和什么元件连接?(这是最重要的线索…