C++编程思想 第2卷 第3章 深入理解字符串 对字符串进行操作 替换字符串中的字符

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对象
 

猜你喜欢

转载自blog.csdn.net/eyetired/article/details/81665130