除了与顺序容器共同的操作之外,string 类型还提供了一些额外的操作。

构造string的其它方法

额外的 string 操作_字符串

char noNull[] = { 'H','i' };
string s1(cp);		//拷贝cp中的值,直到遇到空字符
string s2(noNull,2);	//从noNull拷贝两个字符
string s3(noNull);	//未定义,noNull不是以空字符结束
string s4(cp+6,5);	//从cp[6]开始,拷贝5个字符
string s5(s1,6,5);	//从s1[6]开始,拷贝5个字符
string s6(s1,6);	//从s1[6]开始,直到s1末尾
string s7(s1,6,20);	//从s1[6]开始,直到s1末尾
string s8(s1, 16);	//抛出一个out_of_range异常

当使用 const char* 创建 string 时,指向指向的数组必须是以空字符结尾,拷贝操作遇到空字符而停止。但是如果传递给构造函数一个计数只 ,数组就不必是以空字符结尾。两种未定义的情况:

  • 没有传递计算值并且数组也不是以空字符结尾。
  • 给定了计算值,但是计数值大于数组的大小。

string 拷贝时,可以提供一个可选的开始位置和一个计数值,开始位置必须小于或等于给定 string 的大小,如果大于给定 string 的大小,则会抛出 out_of_range 异常。如果传递一个计数值,则从给定位置开始拷贝这么多字符。不管要求拷贝多少字符,标准库最多拷贝到 string 结尾。

substr

substr 返回一个 string,它是原始 string 的一部分或全部非拷贝,可以传递给 substr 一个可选的开始位置和计数值。
额外的 string 操作_数组_02

string s("Hello World");
string s2 = s.substr(0, 5);
string s3 = s.substr(6);
string s4 = s.substr(6, 11);
string s5 = s.substr(12);	//抛出 out_of_range 异常

开始位置如果超过了 string 的大小,则 substr 函数会抛出 out_of_range 异常。

如果从开始位置加上计数值大于 string 得大小,则 substr 会调整计数值,只拷贝到 string 末尾。

改变 string 的其它方法

除了接受迭代器版本的 inserterase 之外,string 还提供了接受下标的版本。下标指出了开始删除的位置或是insert到给定值之前的位置。

s.insert(s.size(),5,'!');	//在s的末尾插入5个感叹号
s.erase(s.size()-5,5);		//从s删除最后5个字符

标准库 string 类型还提供了接受C风格字符数组的 insertassign 版本。例如,可以将以空字符结尾的字符数组 insert 到或 assign 给一个 string

const char* cp = "Stately,plump Buck";
string s;
s.assign(cp,7);	
s.insert(s.size(),cp+7);

要求 assign 赋值的字符数必须小于等于cp 指向的字符数组大小(不包括末尾的空字符)。

insert 将指定字符插入到指定的位置之前。

也可以指定来自其他 string 或子字符串的字符插入到当前 string 中或赋予当前 string

string s = "some string";
string s2 = "some other string ";
s.insert(0, s2);	//在s中位置0之前插入s2的拷贝	
//在s[0]之前插入s2中s2[0]开始的s2.size()个字符
s.insert(0,s2,0,s2.size());

append 和 replace 函数

string 类定义了两个额外的成员函数:appendreplace。这两个函数可以改变 string 的内容。

append 操作是在 string 末尾进行插入操作的一种简写形式:

string s("C++ Primer"), s2 = s;
s.insert(s.size(), " 4th Ed.");
s2.append(" 4th Ed.");

replace 操作是调用 eraseinsert 的一种形式:

string s("C++ Primer 4th Ed."), s2 = s;
s.erase(11, 3);
s.insert(11, "5th");
s2.replace(11, 3, "5th");

额外的 string 操作_迭代器_03
额外的 string 操作_迭代器_04

改变 string 的多种重载函数

  • assign 总是替换 string 中的所有内容。
  • append 总是将新字符添加到 string 的末尾。
  • replace 可以提供两种指定删除元素范围的方式:
    • 可以通过一个位置和一个长度来指定范围。
    • 可以通过一个迭代器范围来指定。
  • insert 允许使用两种方式指定插入点:使用下标或迭代器,新元素插入到指定的下标或迭代器之前。
string 搜索操作

string 类提供了6个不同的搜素函数,每个函数都有4个重载版本。每个搜索操作都返回一个 string::size_type值,表示匹配发生位置的下标,如果搜索失败,则返回一个名为 string::nposstatic 成员。

标准库 npos 定义为一个 const string::size_type 类型,并初始化值为 -1 。由于此初始值意味着 npos 等于任何 string 最大的可能大小。因为搜索函数返回的是 string::size_type 值,该类型是一个 unsigned 类型,因此,用一个 int 或其它带符号类型类保存这些函数的返回值不是一个好主意。
额外的 string 操作_数组_05
额外的 string 操作_字符串_06

find 函数完成最简单的搜索。它查找参数指定的字符串,若找到,则返回第一个匹配位置的下标,否则返回 npos

string name("AnnaBelle");
auto pos1 = name.find("Anna"); 	//0

查找在给定字符串中任何一个字符匹配的位置:

string numbers("0123456789"), name("r2d2");
auto pos = name.find_first_of(numbers); 	//1


搜索第一个不在参数中的额字符:

string numbers("0123456789");
string dept("03714p3");
auto pos = dept.find_first_not_of(numbers);  //5


指定从哪里开始搜索

可以传递给 find 操作一个可选的开始位置,这个可选的参数指出从哪个位置开始进行搜索,默认情况下,此位置被置为0。

一种常见的程序设计模式是用这个可选参数在字符串中循环地搜索字符串出现的所有位置:

string numbers("0123456789"), name("r2d2");
string::size_type pos = 0;
while((pos = name.find_first_of(numbers,pos))!= string::npos)
{
    cout << "found number at index:" << pos
    << " element is " << name[pos] << endl;
    ++pos;
}


从第二步开始,从 pos 指向的字符开始搜索,这个字符是一个数字,因此 find_first_of 会重复的返回 pos

逆向搜索

标准库还提供了从右向左的搜索操作:

  • rfind 成员函数搜索最后一个匹配,即子字符串最靠右的出现位置。
  • find_last_of 搜索与给定 string 中任何一个字符匹配的最后一个字符。
  • find_last_not_of 搜索最后一个不出现在给定 string 中的字符。
string river("Mississippi");
auto first_pos = river.find("is");	//1
auto last_pos = river.rfind("is");	//4

compare 函数

string 提供了一组 compare 函数,这些函数与C函数的 strcmp 函数很类似,根据s是等于、大于、小于指定的字符串,s.compare 返回0,整数或负数。
额外的 string 操作_4th_07

数值转换

数据与标准库 string 之间的转换。

如果 string 不能转换为一个数值,这些函数抛出一个 invalid_argument 异常。

如果转换得到的数值无法用任何类型来表示,则抛出一个 out_of_range 异常。