insert()函数使程序员放心地向字符串插入字符,而不必担心会使
存储空间越界,或者会改写插入点之后紧跟的字符
replace()有很多的重载版本,最简单的版本用了3个参数:一个参数
用于指示从字符串的什么位置开始改写;第二个参数用于指示从原
字符串中剔除多少个字符,另外一个是替换字符串(包含的字符数
可以与被剔除的字符数不同)
//: C03:StringReplace.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Simple find-and-replace in strings.
#include <cassert>
#include <string>
using namespace std;
int main() {
string s("A piece of text");
string tag("$tag$");
s.insert(8, tag + ' ');
assert(s == "A piece $tag$ of text");
int start = s.find(tag);
assert(start == 8);
assert(tag.size() == 5);
s.replace(start, tag.size(), "hello there");
assert(s == "A piece hello there of text");
} ///:~
无输出
tag串首先插入到s串中,接着进行查找和替换
在调用replace()前程序员应检查是否会找到什么
用一个char* 来进行替换操作,replace()还有一个重载版本,用一个
string来进行替换操作
//: C03:Replace.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include <cassert>
#include <cstddef> // For size_t
#include <string>
using namespace std;
void replaceChars(string& modifyMe,
const string& findMe, const string& newChars) {
// Look in modifyMe for the "find string"
// starting at position 0:
size_t i = modifyMe.find(findMe, 0);
// Did we find the string to replace?
if(i != string::npos)
// Replace the find string with newChars:
modifyMe.replace(i, findMe.size(), newChars);
}
int main() {
string bigNews = "I thought I saw Elvis in a UFO. "
"I have been working too hard.";
string replacement("wig");
string findMe("UFO");
// Find "UFO" in bigNews and overwrite it:
replaceChars(bigNews, findMe, replacement);
assert(bigNews == "I thought I saw Elvis in a "
"wig. I have been working too hard.");
} ///:~
无输出
如果replace找不到要查找的字符串,它返回string::npos
当有新字符复制到现存的一串序列的元素中间时,replace()并不增加
string的存储空间规模,与insert()不同
replace()必要时也会增加存储空间,例如当所做的 “替换”会使原
字符串扩充到超越当前的存储边界
//: C03:ReplaceAndGrow.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include <cassert>
#include <string>
using namespace std;
int main() {
string bigNews("I have been working the grave.");
string replacement("yard shift.");
// The first argument says "replace chars
// beyond the end of the existing string":
bigNews.replace(bigNews.size() - 1,
replacement.size(), replacement);
assert(bigNews == "I have been working the "
"graveyard shift.");
} ///:~
无输出
对replace()的调用使 “替换”超出了原有序列的边界,这与追加操作
是等价的
string类用方法用一个字符替换字符串中各处出现的另一个字符
借助find()和replace()成员函数,容易实现方式
//: C03:ReplaceAll.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#ifndef REPLACEALL_H
#define REPLACEALL_H
#include <string>
std::string& replaceAll(std::string& context,
const std::string& from, const std::string& to);
#endif // REPLACEALL_H ///:~
//: C03:ReplaceAll.cpp {O}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include <cstddef>
#include "ReplaceAll.h"
using namespace std;
string& replaceAll(string& context, const string& from,
const string& to) {
size_t lookHere = 0;
size_t foundHere;
while((foundHere = context.find(from, lookHere))
!= string::npos) {
context.replace(foundHere, from.size(), to);
lookHere = foundHere + to.size();
}
return context;
} ///:~
此处使用的find()版本将开始查找的位置作为第2参数,如果找不到
则返回string::npos
将变量LookHere表示的位置传送到替换串,以防字符串from是字符串
to的子串。
测试replaceAll函数
//: C03:ReplaceAllTest.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
//{L} ReplaceAll
#include <cassert>
#include <iostream>
#include <string>
#include "ReplaceAll.h"
using namespace std;
int main() {
string text = "a man, a plan, a canal, Panama";
replaceAll(text, "an", "XXX");
assert(text == "a mXXX, a plXXX, a cXXXal, PXXXama");
} ///:~
最后assert是对的
无输出
现在才发现 C++ 也可以vs 调试 按f11 如果跳进奇怪的东西就ctrl+f11
可以把assert里面的改掉变成
assert(text == "a mXXX1, a plXXX, a cXXXal, PXXXama");
这样程序就有异常了
输出
Assertion failed: text == "a mXXX1, a plXXX, a cXXXal, PXXXama", file 文件路径省略replacealltest.cpp, line 16
string类自身并不能解决所有可能出现的问题
许多解决方案都是由标准库中的算法完成的,因为string类几乎可与
STL序列等价
用replace()算法将所有单个字符 ‘X’替换为‘Y’
//: C03:StringCharReplace.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include <algorithm>
#include <cassert>
#include <string>
using namespace std;
int main() {
string s("aaaXaaaXXaaXXXaXXXXaaa");
//s "aaaXaaaXXaaXXXaXXXXaaa" std::basic_string<char,std::char_traits<char>,std::allocator<char> >
replace(s.begin(), s.end(), 'X', 'Y');
//- s "aaaXaaaXXaaXXXaXXXXaaa" std::basic_string<char,std::char_traits<char>,std::allocator<char> >
// [size] 22 unsigned int
// [capacity] 31 unsigned int
// [0] 97 'a' char
// [1] 97 'a' char
// [2] 97 'a' char
// [3] 88 'X' char
// [4] 97 'a' char
// [5] 97 'a' char
// [6] 97 'a' char
// [7] 88 'X' char
// [8] 88 'X' char
// [9] 97 'a' char
// [10] 97 'a' char
// [11] 88 'X' char
// [12] 88 'X' char
// [13] 88 'X' char
// [14] 97 'a' char
// [15] 88 'X' char
// [16] 88 'X' char
// [17] 88 'X' char
// [18] 88 'X' char
// [19] 97 'a' char
// [20] 97 'a' char
// [21] 97 'a' char
//变成
// - s "aaaYaaaYYaaYYYaYYYYaaa" std::basic_string<char,std::char_traits<char>,std::allocator<char> >
// [size] 22 unsigned int
// [capacity] 31 unsigned int
// [0] 97 'a' char
// [1] 97 'a' char
// [2] 97 'a' char
// [3] 89 'Y' char
// [4] 97 'a' char
// [5] 97 'a' char
// [6] 97 'a' char
// [7] 89 'Y' char
// [8] 89 'Y' char
// [9] 97 'a' char
// [10] 97 'a' char
// [11] 89 'Y' char
// [12] 89 'Y' char
// [13] 89 'Y' char
// [14] 97 'a' char
// [15] 89 'Y' char
// [16] 89 'Y' char
// [17] 89 'Y' char
// [18] 89 'Y' char
// [19] 97 'a' char
// [20] 97 'a' char
// [21] 97 'a' char
assert(s == "aaaYaaaYYaaYYYaYYYYaaa");
// 返回 std::operator==<char,std::char_traits<char>,std::allocator<char> > true bool
} ///:~
没有弹出异常对话框,说明已经把所有的 ‘X’ 'Y'了
注意,调用的replace()并不是string的成员函数
replace()算法将字符串中出现的某个字符全部用另外一个字符替换掉,
这一点与string::replace()函数不同,因为后者只进行一次替换
replace()算法的工作对象只是单一的对象,它不会替换引用char型
数组或string对象