练习9.43:编写一个函数,接受三个string参数s,oldVal和newVal。使用迭代器及insert和erase函数将s中所有oldVal替换为newVal。测试你的程序,用它替换通用的简写形式,如,将“tho”替换为“though”,将“though”。
答:做题之前先总结一下前面string 的基本操作。
string s(cp) //从位置cp开始拷贝 直到遇到空字符 就是常说的字符串结束符 '\0'
string s(cp,n) //s是从位置cp开始拷贝,共拷贝n个字符。超出范围行为未定义。
string s(s2,pos2) //在s2中从下标pos2开始拷贝 超出范围未定义。
string s(s2,pos,len) //在s2中从下标pos开始 一共要拷贝len个 当len超出长度时最多复制完,不会抛出异常
const char *cp = "Hello World!!!"; //以空字符结束的字符串
char noNull[] = { 'H', 'i' }; //不是以空字符结束
string s1(cp); //拷贝cp指向位置开始的字符串 直到遇到 空字符 '\0'
string s2(cp, 7); //拷贝从 cp指向位置开始的7个字符。
string s3(noNull); //未定义的行为 因为这个noNull的结尾没有空字符。
string s4(noNull, 2); //指定拷贝长度 将复制给定的位置开始的两个字符
string s5(s1, 6);//从s1的下标为6的位置开始 直到结束
string s6(s1, 6, 10);//从下标为6的位置开始 但是指定了拷贝长度为10 不管长度是多少 最多拷贝完
substr操作 (子字符串操作)
string s("hello word");
string s2 = s.substr(0, 5);
string s3 = s.substr(6);
string s4 = s.substr(6, 11);
string s5 = s.substr(12); //超出范围抛出异常
(0,5)0是指的下标 5是长度 同上 最多拷贝到完 不会抛出异常。
支持的其它函数
s.insert(s.size(),5,'1'); //在末尾加5个1
s.erase(s.size()-5,5); //删除最后5个字符
const char *cp = "stately, plump buck";
s.assign(cp,7); //s == "stately"
s.insert(s.size(), cp+7); //s == "stately, plump buck"
上述操作都是和之前的操作一样的规则 比如在末尾插入 用的是 s.insert(s.size(), cp+7).插入到s[size()]处(不存在的) 相当于之前的尾后迭代器。
上述函数接收的参数类型详见 p324
另加追加append 和 replace (调用erase和insert的简写形式)
s.replace(11,3,"fifth");从位置11开始,删除3个字符并插入fifth 位置都是指的下标
/*接受3个string参数 将st中的old_val全部换为new_val*/
void MyReplace(string &st, string old_val, string new_val){
bool flag = 1;
for (auto i = 0; i<st.size(); i++){
for (auto j = 0; j<old_val.size(); j++){
if (st[i + j] != old_val[j]){
flag = 0;
break;
}
}
if (flag){
st.erase(i, old_val.size());
st.insert(i, new_val);
}
flag = 1;
}
}
上面的代码 用循环和相等比较搜索是否有目标字符串,找到目标字符串后,先用erase删除旧的字符串,删除后的下标标志符处在删除后的元素先一个元素。然后再在这个下标对应的元素的上一个位置插入元素,函数insert会完成这一功能(在指定位置之前插入)。
练习9.44:重写上一题的函数,这次使用下标和replace
/*接受3个string参数 将st中的old_val全部换为new_val*/
void MyReplace(string &st, string old_val, string new_val){
bool flag = 1;
for (auto i = 0; i<st.size(); i++){
for (auto j = 0; j<old_val.size(); j++){
if (st[i + j] != old_val[j]){
flag = 0;
break;
}
}
if (flag){
st.replace(i, old_val.size(), new_val);
}
flag = 1;
}
}
练习9.45:编写一个函数,接受一个表示名字的string参数和两个分别表示前缀(如”Mr.”或MS.)和后缀(如“Jr”或“3”)的字符串。使用迭代器及Insert和append函数将前缀和后缀添加到给定的名字中,将生成的新string返回。
void MyReplace(string &st, string before, string after){
st.insert(0, before);
st.append(after);
}
练习9.46:重写上一题的函数,这次使用位置和长度来管理string,并只用insert。
void MyReplace(string &st, string before, string after){
st.insert(0, before);
st.insert(st.size(), after);
}