C++如何判断字符串是否包含子串_C++中find函数查找字符串【检索】

5次阅读

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

C++如何判断字符串是否包含子串_C++中find函数查找字符串【检索】

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 或未以 结尾的 char* 会导致未定义行为。

  • 安全传参:s.find("hello")s.find(std::string("world"))
  • 危险操作:s.find(nullptr)s.find(buf)(若 buf 是未初始化或无结尾 的数组)
  • 区分大小写:默认严格匹配,需忽略大小写时得手动转换或用 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 是唯一合法判据,还有那些看似省事却埋雷的传参方式。

text=ZqhQzanResources