跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

C++ string rfind用法 C++ 字符串反向查找实现【API】

rfind查找失败时返回std::string::npos;该值为size_t类型,等于全1的无符号整数,不可与-1直接比较。 string::rfind 查找失败时返回什么
rfind
找不到子串或字符时,不返回
-1
,而是返回
std::string::npos
—— 这是一个静态常量,类型为
size_t
,值等于
-1
的无符号整数表示(即全 1 的
size_t
)。直接拿它和
-1
比较会触发 隐式类型转换 警告或误判:
std::string s = "hello"; if (s.rfind("xyz") == -1) { /* 错!-1 被转成极大正数,永远不等 */ }
正确写法只能是: 用
s.rfind("xyz") == std::string::npos
或更简洁地写成
s.rfind("xyz") == std::string::npos
(别省略 作用域 ) 注意:
std::string::npos
是唯一合法的“无效位置”标记,不能用
0
、
1
或其他数字代替判断逻辑 rfind 的起始搜索位置参数怎么用
rfind
有带
pos
参数的重载:
rfind(const string&, size_t pos)
。它不是“从 pos 开始往右找”,而是“只在
[0, pos]
范围内反向查找”——即搜索范围上限是
pos
,且查找方向仍是**从右往左**。 例如: 立即学习 “ C++免费学习笔记(深入) ”; C函数速查手册(CHM版) C函数速查手册(CHM版) 下载
std::string s = "ababab"; size_t p = s.rfind("ab", 3); // 在 s[0]~s[3](即 "abab")中找最后的 "ab" → 返回 2 p = s.rfind("ab", 2); // 在 s[0]~s[2](即 "aba")中找 → 返回 0 p = s.rfind("ab", 0); // 只查 s[0] 一个字符 → 若 s[0]=='a' 且要找 "ab",则失败 → npos
pos
超出字符串长度(如
pos > s.length()
)会被自动截断为
s.length()
传
0
是合法的,但范围极小,容易误以为“没找到”其实是“没给够空间找” 想从末尾开始完整反向查找?直接用无参
rfind("xxx")
,别传
s.length()-1
—— 它默认就从末尾开始 char 和 string 版本 rfind 行为差异
rfind
有多个重载,最常用的是:
size_t rfind(char c, size_t pos = npos)
:找单个字符,返回最后一次出现的位置
size_t rfind(const string& str, size_t pos = npos)
:找子串,返回最后一次匹配起始位置 关键区别: 字符版可以高效定位最后一个引号、空格、分隔符等,比如
s.rfind('.') != npos ? s.rfind('.') : -1
常用于取文件扩展名 子串版要注意:它找的是**完整子串匹配**,不是模糊匹配;
"abc".rfind("ab")
返回
0
,但
"abc".rfind("ac")
返回
npos
两者都支持
pos
截断,但字符版对单字符更轻量,子串版内部需做朴素匹配(C++11 起标准未强制要求 KMP,实际 libstd c++ /libc++ 多为朴素) 跨平台兼容性与常见误用坑
rfind
是 C++98 就有的标准接口,所有主流编译器(GCC、Clang、MSVC)行为一致,无需担心语法兼容性。但以下几点极易踩坑: 把
rfind
当作“倒序遍历工具”:它只返回位置,不提供迭代器或范围;需要倒序处理全部匹配?得用循环 +
rfind
不断缩小
pos
,且每次要设
pos = found - 1
(防止重复匹配同一位置) 忽略大小写:标准
rfind
区分大小写;要忽略?得自己转小写再查,或用
std::search
配合自定义谓词 UTF-8 字符串慎用:如果
std::string
存的是 UTF-8 编码 ,
rfind("é")
可能匹配到 字节 序列中间,导致乱码或越界;此时应改用
std::u8string
+ ICU 或 utf8cpp 库 真正难的从来不是调用 API,而是理解
pos
是上界而非起点,以及
npos
必须显式比较 —— 这两点漏掉,调试时会花掉远超编码的时间。

相关文章