当前位置: 首页 > news >正文

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 中第一次出现的位置。

参数说明

  • str:要搜索的字符串
  • strsz:字符串缓冲区大小
  • ch:要查找的字符
  • result:指向指针的指针,用于存储找到的位置

返回值

  • 成功:返回 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. 一致性:统一的错误返回机制

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

  • 正确计算字符串缓冲区大小(通常为 strlen(str) + 1
  • 检查返回值以确保操作成功
  • 正确处理错误情况

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

http://www.dtcms.com/a/462826.html

相关文章:

  • 微观世界的“尺子”,数码显微测量仪的原理与多元应用
  • jsp网站开发实例视频网站自助建设平台百度
  • 海思 / ASR / 展锐芯片实测:2025 随身 WiFi 选购核心参数与场景适配方案
  • 条件语句练习题
  • JLINKKeil调试 软硬件版本驱动对齐
  • wordpress 模板层次结构信息图百度网站关键词优化在哪里做
  • 天津做网站外包公司有哪些网站打开的速度特别慢的原因
  • ElasticSearch与Kibana 入门指南(7.x版本)
  • LLM 与强化学习的新范式:Agentic RL 研究综述
  • wordpress 标签打不开外贸网站推广seo
  • 深圳租赁住房和建设局网站网站设计定位
  • 公司网站建设会议纪要全球速卖通企业类型
  • 一、十天速通Java面试(第三天)
  • 网站怎么seo关键词排名优化推广石家庄专业信息门户网站定制
  • 十堰为企业做网站的单位wordpress建m域名网站
  • anaconda安装及使用
  • 惠来做网站专门做门的网站
  • 合肥专业网站排名推广wordpress显示近几篇微博
  • 智能推送定义怎么写
  • 认识Emitter:进程内的事件处理专家
  • RDK X5 镜像备份(详细)
  • 郑州建网站企业seo核心技术排名
  • 动易网站地图五款wordpress常用加速插件
  • 网站建设和运行费用中国国家城乡建设部网站
  • 5G与6G:从“万物互联“到“智能无界“的跨越
  • ISAC 4D Imaging System Based on 5G Downlink Millimeter Wave Signal
  • 建设银行网站点不进去了怎么办青岛网站有限公司
  • 开源模型应用落地-FireRedTTS2-从文本到声音的智能跃迁-“声”临其境(三)
  • 广州住房和城乡建设厅网站渭南网站建设公司定制网站建设公司
  • day03_八大基本数类型+程序交互+基本运算符+流程控制语句