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' charassert(s == "aaaYaaaYYaaYYYaYYYYaaa");// 返回 std::operator==<char,std::char_traits<char>,std::allocator<char> > true bool} ///:~
没有弹出异常对话框,说明已经把所有的 ‘X’ 'Y'了
注意,调用的replace()并不是string的成员函数
replace()算法将字符串中出现的某个字符全部用另外一个字符替换掉,
这一点与string::replace()函数不同,因为后者只进行一次替换
replace()算法的工作对象只是单一的对象,它不会替换引用char型
数组或string对象
C++编程思想 第2卷 第3章 深入理解字符串 对字符串进行操作 替换字符串中的字符相关推荐
- C++编程思想 第2卷 第11章 并发 线程间协作 用队列解决线程处理的问题 适当地进行烘烤
解决ToastOMatic.cpp存在的问题 可以在加工期间使用TQueue管理烤面包 需要实际的烤面包对象 它们保持显示了其状态 //: C11:ToastOMaticMarkII.cpp {Run ...
- C++编程思想 第1卷 第11章 引用和拷贝构造函数 拷贝构造函数 拷贝构造函数
编译器对如何从现有的对象产生新的对象进行了假定. 当通过按值传递的方式传递一个对象时,就创立了一个新对象,函数体内的 对象是由函数体外的原来存在的对象传递的 编译器假定我们想使用位拷贝来创建对象 每当 ...
- C++编程思想 第2卷 第10章 设计模式 构建器模式:创建复杂对象
构建器 Builder 模式的模板是将对象的创建与它的 表示法 分开 意味着 创建保持原状 但是产生对象 的表示法 不同 作为模型的自行车按照其内心来选择零部件组装一辆自行车 一个构建器与每个自行车 ...
- C++编程思想 第1卷 第9章 内联函数 内联函数 访问器和修改器
一些人进一步访问函数的概念分为访问器 accessor,用于从一个对象读状态 信息和 修改器 mutator 用于修改状态信息. 而且,可以用重载函数为访问器 和修改器提供相同函数名,调用函数的方式决 ...
- 《Java编程思想》读书笔记 第十三章 字符串
<Java编程思想>读书笔记 第十三章 字符串 不可变String String对象是不可变的,每一个看起来会修改String值的方法,实际上都是创建一个全新的String对象,以及包含修 ...
- 《Java编程思想》学习笔记(一)——再度理解OOP
实践是认识的来源和基础.是认识的动力.是检验其真理性的标准.工作一年后再回过头来看看,还是学生的时候对编程语言产生的各种疑问,突然间,好像有了那么点儿豁然开朗的感觉.但,真正的豁然开朗还是在品读了&l ...
- java现有一个泛型类 提供数组排序功能,java编程思想读书笔记 第十六章 数组
数组,你可以创建并组装它们,通过使用整型索引值访问它们的元素,并且它们的尺寸不能改变. 1.数组为什么特殊 数组与其他种类的容器之间的区别有三方面:效率.类型和保存基本类型的能力.在Java中数组是一 ...
- java编程思想第四版第三章要点习题
使用"简短的" 和正常的 打印语句来编写一个程序 package net.mindview.util;public class Print {/*** 不带有回车* @param ...
- 《JAVA编程思想》学习笔记——第三章 操作符
在最底层,Java的数据是通过适用操作符来操作的. 几乎所有的操作符都只能操作"基本类型".例外的操作符是"=","=="和"!= ...
最新文章
- matlab imadjust 用 opencv改写
- QT学习:常用SQL命令
- Exchange端口列表
- SAP ABAP的权限检查跟踪(Authorization trace)工具使用步骤介绍
- ril.java_RIL.java里request流程
- 1. K近邻算法(KNN)
- Kubernetes 搭建 ES 集群(存储使用 cephfs)
- 555定时器+74系列芯片搭建八路抢答器,30s倒计时,附Proteus仿真等
- 编译bug can not be used when making a shared object; recompile with -fPIC
- 51单片机驱动LCD1602显示原理及例程
- 数学建模国赛论文latex代码汇总
- 搜狗收录提交入口之搜狗泛目录实现
- srt格式导入pr乱码_PR软件导入字幕文件后显示乱码如何解决
- Mac上利用iTunes制作铃声
- 【可见光室内定位】(三)基于图像传感器CMOS的可见光室内定位技术
- 【NLP】Seq2Seq与Attention(Neural Machine Translation by Jointly Learning to Align and Translate)回顾
- 微波雷达传感器感应模块,智能安防过滤雨水树叶干扰技术应用
- JSON和XML的区别
- 虚拟化技术—基础(1)
- echarts仪表盘式进度条