8.8.3 访问与修改字符串
我们可以通过使用下标运算符[]来访问string对象中的任何字符从而读取或重写它。举例如下:
- string sentence("Too many cooks spoil the broth.");
- for(size_t i = 0; i<sentence.length(); i++)
- if(sentence[i] == ' ')
- sentence[i] = '*';
这段代码仅仅依次检查sentence字符串中的每个字符,看看它是否为空格,如果是,则用星号替换该字符。
用at()成员函数与用[]运算符得到的结果相同:
- string sentence("Too many cooks spoil the broth.");
- for(size_t i = 0; i<sentence.length(); i++)
- if(sentence.at(i) == ' ')
- sentence.at(i) = '*';
这段代码与上一段代码的功能完全相同,那么,使用[]与使用at()的区别在哪里呢?利用下标值比使用at()函数快,不过缺点是没有检查索引的有效性。如果索引超出了范围,那么使用下标运算符的结果将不确定。另一方面,at()函数稍微慢一点儿,但它会检查索引的有效性,如果索引无效,该函数就会抛出一个out_of_range异常。当索引值有可能超出范围时,可以使用at()函数,在这种情况下我们把代码放在try块中,并恰当地处理异常。如果我们能确信不会出现索引超出范围的情况,就使用[]运算符。
我们可以提取现有string对象的一部分作为一个新的string对象。例如:
- string sentence("Too many cooks spoil the broth.");
- string substring = sentence.substr(4, 10); // Extracts "many cooks"
substr()函数的第一个实参是要提取的子串的第一个字符,第二个实参是子串中的字符个数。
通过使用字符串对象的append()函数,我们可以在字符串末尾添加一个或多个字符。该函数有几个版本;包括向调用该函数的对象附加一个或多个给定字符、一个字符串字面值或者一个string对象。例如:
- string phrase("The higher");
- string word("fewer");
- phrase.append(1, ' '); // Append one space
- phrase.append("the "); // Append a string literal
- phrase.append(word); // Append a string object
- phrase.append(2, '!'); // Append two exclamation marks
当执行这个代码序列后,phrase会被改为"The higher the fewer!!"。使用带两个实参的append()版本时,第一个实参是将被附加第二个实参指定的字符的次数。当我们调用append()时,函数返回对调用该函数的对象的引用,因此我们可以在一个语句中写出上面4个append()调用:
- phrase.append(1, ' ').append("the ").append(word).append(2, '!');
我们也可以用append()将字符串字面值的一部分或string对象的一部分附加到一个现有字符串后面:
- string phrase("The more the merrier.");
- string query("Any");
- query.append(phrase, 3, 5).append(1, ' ');
执行这些语句的结果是query会包含字符串"Any more "。在最后一个语句中,对append()函数的第一个调用有3个实参:
第一个实参phrase是从中提取字符并附加到query后面的string对象。
第二个实参3是要提取的第一个字符的索引位置。
第三个实参5是要附加的字符总数。
因此这个调用会将子串"more"附加到query后面。对append()函数的第二个调用在query后面加上一个问号。
如果我们想向一个字符串后面附加一个字符,可以用push_back()函数作为append()的替换函数。用法如下:
- query.push_back('*');
此代码向query字符串的末尾附加一个星号字符。
有时,仅仅向字符串末尾添加字符还不够。有时候可能需要在字符串中间的某个位置插入一个或多个字符。insert()函数的各种版本可以为我们完成这一任务:
- string saying("A horse");
- string word("blind");
- string sentence("He is as good as gold.");
- string phrase("a wink too far");
- saying.insert(1, " "); // Insert a space character
- saying.insert(2, word); // Insert a string object
- saying.insert(2, "nodding", 3); // Insert 3
characters of a string literal - saying.insert(5, sentence, 2, 15); //Insert part of a
string at position 5 - saying.insert(20, phrase, 0, 9); // Insert part
of a string at position 20 - saying.insert(29, " ").insert(30, "a poor do", 0, 2);
执行上面的语句后,saying将包含字符串"A nod is as good as a wink to a blind horse"。insert()的各版本的形参如表8-1所示。
表 8-1
|
函 数 原 型< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> |
说 明 |
|
string& insert(size_t index,
const char* pstring) |
在index位置插入以
空字符结尾的字符串pstring |
|
string& insert(size_t index,
const string astring) |
在index位置插入string对象astring |
|
string& insert(size_t index,
const char* pstring,
size_t count) |
在index位置插入以空
字符结尾的字符串pstring
中的前count个字符 |
|
string& insert(size_t index,
const string astring,
size_t count) |
在index位置插入string对象
astring中的前count个字符 |
|
string& insert(size_t index,
const string astring,
size_t start,
size_t count) |
插入string对象astring中从
start位置的字符开始的count个
字符;子串插入在index位置 |
|
string& insert(size_t index,
const char* pstring,
size_t start,
size_t count) |
插入以空字符结尾的字符串pstring
中从start位置的字符开始的count
字符;子串插入在index位置 |
在insert()的各个版本中,返回对调用该函数的string对象的一个引用。这样,就可以像上面代码片段中的最后一个语句那样将所有调用链接在一起。
表8-1并不是insert()函数的完整集合,但是我们可以用该表中的版本做任何事情。其他版本用第10章将介绍的迭代器(iterator)作为实参。
我们可以通过调用swap()成员函数来交换封装在两个string对象之间的字符串。例如:
- string phrase("The more the merrier.");
- string query("Any");
- query.swap(phrase);
query中的结果包含字符串"The more the merrier."phrase包含字符串"Any"。当然,执行phrase.swap(query)也能得到同样的效果。
如果我们需要将一个字符串对象转换为以空字符结尾的字符串,可以用c_str()函数来完成。例如:
- string phrase("The higher the fewer");
- const char *pstring = phrase.c_str();
c_str()函数返回一个指向以空字符结尾的字符串的指针,该字符串的内容与string对象相同。
我们也可以通过调用data()成员函数来获得一个字符串对象(作为char类型的元素的数组)的内容。注意,该数组仅包含字符串对象中的字符,不包括结尾的空字符。
我们可以通过调用字符串对象的replace()成员函数来替换字符串对象的一部分。它也有几个版本,如表8-2所示。
表 8-2
|
函 数 原 型 |
说 明 |
|
string& replace(size_t index,
size_t count,
const char* pstring) |
用pstring中的前count个字符替换
从index位置开始的count个字符 |
|
string& replace(size_t index,
size_t count,
const string astring) |
用astring中的前count个字符替换从
index位置开始的count个字符 |
|
string& replace(size_t index,
size_t count1,
const char* pstring,
size_t count2) |
用pstring中第一个到第count2个字符
替换从index位置开始的count1个字符。
这个版本可以替换比所替换
的子串长或短的子串 |
|
string& replace(size_t index1,
size_t count1,
const string astring,
size_t index2,
size_t count2) |
用astring中从index2位置开始的count2
个字符替换从index1位置开
始的count1个字符 |
|
string& replace(size_t index,
size_t count1,
size_t count2,
char ch) |
用count2个字符ch替换从index位置
开始的count1个字符 |
表8-2的各个版本都会返回对调用该函数的string对象的引用。
举例如下:
- string proverb("A nod is as good as a wink to a blind horse");
- string sentence("It's bath time!");
- proverb.replace(38, 5, sentence, 5, 3);
这段代码采用表8-2中replace()函数的第四个版本,用"bat"替换字符串proverb中的"horse"。