最直接判断子串存在的方式是用str.find("abc") != std::string::npos;错误写法是== -1,因类型转换导致逻辑失效;需避免传入nullptr或未终止的char*,高频场景可考虑string_view或循环查找。

用 std::string::find 判断子串是否存在最直接
std::string::find 返回 size_t 类型,查不到时返回 std::string::npos(值为 -1 的无符号整数)。别用 == -1 判断,会因类型转换出错。
- 正确写法:
str.find("abc") != std::string::npos - 错误写法:
str.find("abc") == -1(-1被转成极大正数,永远不等) - 注意:返回值是位置索引,不是布尔值,但可安全用于条件判断
find 的重载版本和常见误用场景
有多个重载,最常用的是 find(const std::string&) 和 find(const char*)。传入 nullptr 或未以 \0 结尾的 char* 会导致未定义行为。
- 安全传参:
s.find("hello")、s.find(std::string("world")) - 危险操作:
s.find(nullptr)、s.find(buf)(若buf是未初始化或无结尾\0的数组) - 区分大小写:默认严格匹配,需忽略大小写时得手动转换或用
std::search+ 自定义谓词
性能与替代方案:find 不是万能的
单次查找用 find 没问题,但高频、多模式、或需全匹配语义时,它可能不是最优解。
- 重复查找同一子串?考虑缓存
std::string_view避免构造临时std::string - 要找所有出现位置?不能只调一次
find,得循环:pos = s.find(sub, pos); pos != std::string::npos; pos += sub.length() - 子串长度固定且较短(如 2~4 字节)?有时用
memcmp或字面量比较更快,尤其在嵌入式或 hot path 中
兼容性注意:C++17 起支持 std::string_view::find
如果原始字符串是字面量或已知生命周期足够长的 const char*,用 std::string_view 可避免拷贝,且接口一致。
立即学习“C++免费学习笔记(深入)”;
- 示例:
std::string_view sv{"hello world"}; bool found = sv.find("world") != sv.npos; - 旧标准(C++11/14)不支持
string_view,得退回到const char*+std::strstr(C 风格,但不支持std::string直接传参) - 跨平台项目中,若需支持 MSVC 2015 或更早,
string_view不可用,必须用std::string::find
if (s.find("target") != std::string::npos) 就够了,但得记牢 npos 是唯一合法判据,还有那些看似省事却埋雷的传参方式。










