除了在上一节提到的构造函数外,还有另外三个构造函数:
string s(cp, n)s是cp指向的数组中前n个字符的拷贝。此数组至少应包含n个字符string s(s2, pos2)s是string s2从下标pos2开始的字符的拷贝。若pos2>s.size(),构造函数的行为无定义string s(s2, pos2, len2)s是string s2 从下标 pos2 开始 len2 个字符的拷贝。若pos2 > s2.size(),构造函数的行为未定义。不管 len2 的值是多少,构造函数至多拷贝s2.size() - pos2 个字符 const char *cp = "Hello World!!!"; //以空字符结束的数组 char noNull[] = {'H', 'i'}; //不是以空字符串结束的数组 string s1(cp); //拷贝cp中的字符直到遇到空字符;s1 == "Hello World!!!" string s2(noNull, 2); //从noNull拷贝两个字符;s2 == "Hi"; string s3(noNull); //未定义 string s4(cp + 6, 5); //从cp[6]开始拷贝5个字符;s4 == "World" string s5(s1, 6, 5); //从s1[6]开始拷贝5个字符;s5 == "World" string s6(s1, 6); //从s1[6]开始拷贝,直至s1末尾;s6 == "World!!!" string s7(s1, 6, 20); //拷贝直到s1末尾;s7 == "World!!!" string s8(s1, 16); //抛出一个out_of_range异常注意: (1)当我们从一个 const char* 创建 string 时,指针指向的数组必须以空字符结尾,拷贝操作遇到空字符时停止;若传递的参数中有计数值,数组不必以空字符结尾; (2)若未传递计数值且数组未以空字符结尾,或给定计数值大于数组大小,则构造函数的行为是未定义的。 (3)从 string 拷贝字符时,提供的开始位置如果大于size,则构造函数抛出一个out_of_range异常
如果开始位置超过了string的大小,则substr函数抛出一个out_of_range异常
string s("Hello World"); string s2 = s.substr(0, 5); //s2 = hello string s3 = s.substr(6); //s3 = world string s4 = s.substr(6, 11); //s3 = world string s5 = s.substr(12); //抛出一个out_of_range异常注意: (1)assign 和 append 函数无须指定要替换 string 的哪部分:assign总是替换 string 中的所有内容,append 总是将新字符追加到 string 末尾。 (2)replace 函数提供了两种指定删除元素范围的方式:可以通过一个位置和一个长度来指定范围;也可以通过一个迭代器范围来指定。insert 函数允许我们用两种方式指定插入点:用一个下标或一个迭代器。 (3)并不是每一个函数都支持所有形式的参数。例如:insert 就不支持下标和初始化列表参数。
每个搜索操作都返回一个string::size type值,表示匹配发生位置的下标。如果搜索失败,则返回一个名为string::npos的static成员。 标准库将npos定义为一个const string::size_type类型,并初始化为值-1。由于npos是一个unsigned类型,此初始值意味着npos等于任何string最大的可能大小。 string搜索操作:
s.find(args)查找s中args第一次出现的位置s.rfind(args)查找s中args最后一次出现的位置s.find_first_of(args)在s中查找args中任何一个字符第一次出现的位置s.find_last_of(args)在s中查找args中任何一个字符最后一次出现的位置s.find_first_not_of(args)在s中查找第一个不在args中的字符s.find_last_not_of(args)在s中查找最后一个不在args中的字符args必须是以下形式之一: c, pos 从s中位置pos开始查找字符c。pos默认为0 s2, pos 从s中位置pos开始查找字符串s2。pos默认为0 cp, pos 从s中位置pos开始查找指针cp指向的以空字符结尾的c风格字符串。pos默认为0 cp, pos, n 从s中位置pos开始查找指针cp指向的数组的前n个字符。pos和n无默认值
可传递给find操作一个可选的开始位置。可选参数指出从哪个位置开始进行搜索。默认情况下,此位置被置0
string :: size_type pos = 0; //每步循环查找name中下一个数 while ((pos = name.find_first_of(numbers, pos)) != string :: npos) { cout << "found number at index:" << pos << "element is " << name[pos] << endl; ++pos; //移动到下一个字符 }rfind成员函数搜索最后一个匹配,即子字符串最靠右的出现位置:
string river("Mississippi"); auto first_pos = river.find("is"); //返回1 auto last_pos = river.rfind("is"); //返回4find_last函数的功能与find_first函数相似,只是它们返回最后一个匹配。
标准库string类型提供一组compare函数,这些函数与C标准库的strcmp函数很相似。根据s是等于、大于还是小于参数指定的字符串,s.compare返回0,正数或负数。
s.compare的几种参数形式:
s2比较s和s2pos1, n1, s2将 s 中从 pos1 开始的 n1 个字符与 s2 进行比较pos1, n1, s2, pos2, n2将 s 中从 pos1 开始的 n1 个字符与 s2 中从 pos2 开始的 n2 个字符进行比较cp比较 s 与 cp 指向的以空字符结尾的字符数组pos1, n1, cp将 s 中从 pos1 开始的 n1 个字符与 cp 指向的以空字符结尾的字符数组进行比较pos1, n1, cp, n2将 s 中从 pos1 开始的 n1 个字符与指针 cp 指向的地址开始的 n2 个字符进行比较新标准引入多个函数,实现数值与标准库string之间的转换:
int i = 42; string s = to_string(i); //将整数i转换为字符表示形式 double d = stod(s); //将字符串s转换为浮点数string和数值之间的转换:
to_string(val)一组重载函数,返回数值 val 的 string 表示。val 可以是任何算术类型。stoi(s,p,b)把字符串 s 从 p 开始转换成b 进制的int,b 的默认值为10。p 是 size_t 指针,用来保存 s 中第一个非数值字符的下标,p 默认是0stol(s,p,b)把字符串 s 从 p 开始转换成 b 进制的 longstoul(s,p,b)把字符串 s 从 p 开始转换成 b 进制的 unsigned longstoll(s,p,b)把字符串 s 从 p 开始转换成 b 进制的 long longstoull(s,p,b)把字符串 s 从 p 开始转换成 b 进制的 unsigned long longstof(s,p)把字符串 s 从 p 开始转换成 floatstod(s,p)把字符串 s 从 p 开始转换成 doublestold(s,p)把字符串 s 从 p 开始转换成 long double注意: (1)要转换为数值的string 中第一个非空白符必须是数值中可能出现的字符:
string s2 = "pi = 3.14"; //转换 s2 中以数字开始的第一个子串,结果d = 3.14 d = stod(s2.substr(s2.find_first_of("+-.0123456789")))(2)stod读取传递的参数,处理其中字符,直至遇到不可能是数值的一部分字符。 (3)如果 string 不能转换为一个数值,这些函数抛出一个 invaild_argument 异常;如果转换得到的数值无法用任何类型来表示,则抛出一个 out_of_range 异常。
举个栗子: 编写程序处理一个vector< string > ,其元素都为整型值。计算vector中所有元素之和:
#include <iostream> #include <vector> #include <string> using namespace std; int main() { vector<string> vs = {"123", "456", "789"}; int sum = 0; for (auto iter = vs.begin(); iter != vs.end(); iter++) sum += stoi(*iter); cout << "和:" << sum << endl; return 0; }