16. string下

16. string下
string 的查找方法

string 类提供 find() 方法的多个重载版本:从指定位置 pos(默认 0)开始查找子字符串(string 或 C 风格字符串)、C 风格字符串的前 n 个字符、或单个字符。找到则返回该子字符串/字符首次出现时其首字符的索引,否则返回 string::npos。

查找是字符串处理的常见需求,重载版本覆盖“按对象、按 C 风格字符串、按子串、按字符”多种查找来源。

由于索引从 0 开始,string::npos 它比最大索引值大 1,因此可用它来表示“没有找到”。第二个可选参数 pos 指定搜索的起始位置。

std::string target("apiary"); int loc = target.find('a'); // 查找字符 'a',返回首次出现位置 loc = target.find('a', loc + 1); // 从 loc+1 开始继续查找 if (loc == std::string::npos) { // npos 表示没有找到 // 处理未找到的情况 }
相关查找方法族

string库还提供与find()相关的查找方法族:rfind()(查找子字符串或字符最后一次出现的位置)、find_first_of()(查找参数中任何一个字符首次出现的位置)、find_last_of()(查找参数中任一字符最后一次出现的位置)、find_first_not_of()(查找第一个不包含在参数中的字符)、find_last_not_of(),它们的重载函数特征标都与 find() 方法相同。

这些方法覆盖了字符串查找的常见变体——正向/反向、属于字符集/不属于字符集,避免为每种查询手写循环。

规则(限制):find_first_of("hark") 返回 "hark" 中各字母在目标字符串中首次出现的位置(如 'r' 在 "cobra" 中的索引 3);find_first_not_of("hark") 返回目标中第一个不在参数中的字符位置(如 "cobra" 中的 'c',因为 "hark" 中没有 c)。

std::string snake1("cobra"); int w1 = snake1.find_first_of("hark"); // 返回 'r' 的位置 3 int w2 = snake1.find_last_of("hark"); // 返回 'a' 的位置(最后一次出现) int w3 = snake1.find_first_not_of("hark"); // 返回 'c' 的位置(首个不在参数中的字符)
string 库的其他工具函数

string 库还提供完成下述功能的函数:

  1. 删除字符串的部分或全部内容

  2. 用一个字符串的部分或全部内容替换另一个字符串的部分或全部内容

  3. 将数据插入到字符串中或删除字符串中的数据

  4. 将一个字符串的部分或全部内容与另一个字符串的部分或全部内容进行比较

  5. 从字符串中提取子字符串、将一个字符串中的内容复制到另一个字符串中

  6. 交换两个字符串的内容。

    这些函数中的大多数都被重载,以便能够同时处理 C 风格字符串和 string 对象。

#include <iostream> #include <string> using namespace std; ​ int main() { string s = "Hello World"; cout << "1. 原始: " << s << endl; ​ // ① 提取子串 (substr) string sub = s.substr(6, 5); // "World" cout << "2. 提取: " << sub << endl; ​ // ② 插入 (insert) —— 在 Hello 和 World 之间加逗号 s.insert(5, ","); // "Hello, World" cout << "3. 插入: " << s << endl; ​ // ③ 删除 (erase) —— 删掉那个逗号 s.erase(5, 1); // 回到 "Hello World" cout << "4. 删除: " << s << endl; ​ // ④ 替换 (replace) —— 把 World 换成 C++ s.replace(6, 5, "C++"); // "Hello C++" cout << "5. 替换: " << s << endl; ​ // ⑤ 比较 (compare) —— 跟目标字符串比较 int cmp = s.compare("Hello C++"); cout << "6. 比较: " << cmp << " (0表示相等)" << endl; ​ // ⑥ 复制 (assign) —— 把 s 复制给 s2 string s2; s2.assign(s); cout << "7. 复制: s2 = " << s2 << endl; ​ // ⑦ 交换 (swap) —— s 变成子串,子串变成 s 的内容 s.swap(sub); cout << "8. 交换后 s = " << s << ", sub = " << sub << endl; ​ // 附加验证:清空 (clear) s.clear(); cout << "9. 清空后 s 是否为空? " << (s.empty() ? "是" : "否") << endl; ​ return 0; }
自动调整大小:capacity() 与 reserve()

字符串追加字符时,不能简单地加大已有字符串(相邻内存可能被占用),因此需要分配新的内存块并把原内容复制过去。为避免频繁分配,很多 C++ 实现会分配一个比实际字符串大的内存块,为字符串预留增大空间;当字符串超过内存块大小时,程序分配一个大小为原来两倍的新内存块。方法 capacity() 返回当前分配给字符串的内存块的大小,reserve() 让你能够请求内存块的最小长度。

std::string empty; // 空字符串 std::string larger("Elephants are a girl's best friend"); size_t cap = empty.capacity(); // 返回当前分配的内存块大小 empty.reserve(50); // 请求内存块最小长度为 50
c_str() 方法:获取 C 风格字符串

c_str() 方法返回一个指向 C 风格字符串的指针,该 C 风格字符串的内容与用于调用 c_str() 方法的 string 对象相同。c_str() 提供了从 string 对象到 C 风格字符串的转换通道。

std::string filename; // 存储文件名的 string 对象 // filename 可通过输入获得 std::ofstream fout; fout.open(filename.c_str()); // c_str() 提供 C 风格字符串参数
basic_string 模板与字符串种类

string 库实际上基于一个模板类:template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>> class basic_string {...};。模板 basic_string 有 4 个具体化,每个具体化都有一个 typedef 名称:string(basic_string<char>)、wstring(basic_string<wchar_t>)、u16string(basic_string<char16_t>,C++11)、u32string(basic_string<char32_t>,C++11)。traits 类描述关于选定字符类型的特定情况(如如何对值进行比较),Allocator 是管理内存分配的类(默认使用 new 和 delete)。

typedef std::basic_string<char> string; // 4 个具体化之一 typedef std::basic_string<wchar_t> wstring; // 宽字符字符串 typedef std::basic_string<char16_t> u16string; // C++11:UTF-16 字符串 typedef std::basic_string<char32_t> u32string; // C++11:UTF-32 字符串
知识点描述
string 类与头文件<string>支持 string 类(basic_string<char>的 typedef);<cstring>只支持 C 风格字符串函数;size_type为依赖实现的整型,npos为最大长度。
string 的构造函数覆盖 C 风格字符串、字符填充、复制、默认、前缀、指针区间、子串等来源;区间为[begin, end);对象名不作地址,须&five[i]
C++11 新增构造函数移动构造函数(转移资源、非 const)与初始化列表构造函数(使列表初始化语法可用)。
string 输入方式>>读单词、getline读行(均可指定分界符);string 版自动调整大小不截断;C 风格版本是istream方法,string 版是独立函数。
getline 终止与流状态文件尾(eofbit)、分界字符(删除不存储)、达到最大允许值(failbit);流有 eofbit/failbit/badbit/goodbit 状态位。
自定义分界符的影响指定:后换行符成为常规字符,会出现在读入的字符串中。
string 比较与长度6 个关系运算符三重载覆盖三种组合;size()length()等价(STL 兼容性)。
find 查找方法pos起查找子串/子串前 n 字符/单字符;未找到返回npos
相关查找方法族rfind(反向)、find_first_of/find_last_of(属于字符集)、find_first_not_of/find_last_not_of(不属于字符集)。
string 的其他工具函数删除、替换、插入、比较、提取子串、复制、交换;多数重载以兼容 C 风格字符串与 string 对象。
自动调整大小 capacity/reserve追加时分配更大内存块(常按两倍增长)避免频繁分配;capacity()返回当前内存块大小,reserve()请求最小长度,容量随实现而异。
c_str() 方法返回内容与 string 对象相同的 C 风格字符串指针,用于需要const char*的接口(如文件打开)。
basic_string 模板与字符串种类basic_string<charT, traits, Allocator>有 string/wstring/u16string/u32string 四个 typedef 具体化;traits 描述字符特性,Allocator 管理内存分配。