1.assign()

原型:

//string (1)
basic_string& assign (const basic_string& str);
//substring (2)
basic_string& assign (const basic_string& str, size_type subpos, size_type sublen);
//c-string (3)
basic_string& assign (const charT* s);
//buffer (4)
basic_string& assign (const charT* s, size_type n);
//ill (5)
basic_string& assign (size_type n, charT c);
//range (6)
template <class InputIterator>
basic_string& assign (InputIterator first, InputIterator last);

ps:charT是类模板basic_string的第1个参数,指定了字符串中字符的类型。用char实例化basic_string,得到string(可参考在下的“C++ string到底是什么”)。所以, 在string中,charT就是char。

示例:

#include<iostream>
#include<string> using namespace std; int main()
{
string str1("");
string str = "";
char* str2 = "abcdef";
str.assign(str1);
cout << str << endl;//123456 可见执行assign()后,str将被重写
str.assign(str1, , );
cout << str << endl;//345 从位置2开始的3个字符
str.assign(str1, , );//超出范围
cout << str << endl;//
cout << str.length() << endl;//5 可见没有空格
str.assign(str1, , str1.npos);//后面介绍npos
cout << str << endl;//3456 从位置2到末尾的字符给str
str.assign(, 'X');
cout << str << endl;//XXXXX
str.assign(str1.begin(), str1.end() - );
cout << str << endl;//12345 从开头到结尾-1(即倒数第个字符)
//str.assign(str1.begin() + 4, str1.end() - 4);//不能反着来,即试图将以str1.begin() + 4(5)开头,以str1.end() - 4(2)结尾的5432给str是不行的
//cout << str << endl; //这样会出现运行时错误
str.assign(str1.begin() + , str1.end() - );//前后指向同一字符(3),这样可以
cout << str << endl;//
str.assign(str1.begin() + , str1.end() - );//这个却可以
cout << str << endl;//空行
cout << str.length() << endl;//
str.assign("abcdefg", );
cout << str << endl;//abcdef 将abcdefg的前6个字符给str
str.assign("abcdefg", );//超出范围
cout << str << endl;//abcdefg+乱码
cout << str.length() << endl;//10 说明将"abcdefg+3个空格"给了str
str.assign(, 0x41);
cout << str << endl;//AAA 可以使用16进制的ASCII码 0x41换成10进制是65,是A的ASCII码
str.assign(str2);
cout << str << endl;//abcdef
str.assign(str2, , );
cout << str << endl;//cde 对char*型也可以
return ;
}

以上代码中有一句
str.assign(str1, 2, str1.npos);
这里我们解释npos:
它的定义如下:
std::string::npos
static const size_t npos = -1;
它是size_t类型的最大值,有些编译器也将它置为string对象的最大容量(按字节算,包括'\0'),而有些编译器不是,我们在后边将会看到。
为什么是最大呢?
-1用反码存储(32位),就是32个1,而size_t是无符号整型,所以,32个1的2进制转化为10进制就是2的32次方-1,即4294967295。
看下面一段验证代码:

#include<iostream>
#include<string> using namespace std; int main()
{
string str1 = "";
cout << str1.npos << endl;//
cout << (str1.npos == -) << endl;//
cout << str1.max_size() << endl;//4294967294 1073741820(=2^30-4)
return ;
}

其中,4294967294是VS2013上的结果,可见max_size()不包括'\0',1073741820是CodeBlocks12.11上的结果。
由此,我们可知,str.assign(str1, 2, str1.npos);等价于str.assign(str1, 2, 4294967294);

另外,在C++11中,还有两个重载的assign()函数,它们的原型分别是:

//initializer list(7)
basic_string& assign (initializer_list<charT> il);
//move (8)
basic_string& assign (basic_string&& str) noexcept;

其中,(7)与list容器有关,而(8)与右值引用和移动语义有关,这里我们暂不详述。
对于(8)中的noexcept关键字,它声明了函数不会抛出异常(当然函数不是真的就永远都不会抛出异常,比如该函数A(声明为noexcept)中调用了另一个函数B,而函数B中有抛出异常语句,那么,当我们调用函数A是,就可能抛出异常),由于noexcept不是本文的重点,这里我们不详述,有兴趣的读者可以自行查阅资料了解学习相关内容。

2.swap()

原型:void swap (basic_string& str);
只有这一个,要交换就交换整个字符串,这里没有针对子串的操作。
不举例。

3.erase()

原型:

//sequence (1)
basic_string& erase (size_type pos = , size_type len = npos);
//character (2)
iterator erase (iterator p);
//range (3)
iterator erase (iterator first, iterator last);

说明:
注意到basic_string& erase (size_type pos = 0, size_type len = npos);给出了默认参数,这样,我们在使用该函数时,就可以省略第2个参数,效果是删除从第1个参数所指位置(包括该位置)起的所有字符(正如下边示例中有关str3的操作和输出)。原因是len=npos,而npos一定大于string对象的最大长度。

示例:

#include<iostream>
#include<string> using namespace std; int main()
{
string str1("");
string str2("");
string str3("");
string str4("");
string str5("");
string str6("");
string str7("");
string str8("");
str1.erase(, );
cout << str1 << endl;//
str2.erase(, ); cout << endl;//空行
str3.erase();//注意这里的参数值不能超过str3.length(),否则会出现运行时错误等于是输出空行,相当于删除'\0'及其后面的(当然后面什么也没有,
//因为'\0'已经是最后一个)
cout << str3 << endl;//1234567 当省略第2个参数时,删除第1个参数所指位置起(即包括该位置)的所有字符
//str4.erase(10, 5);//这么做不行
//cout << str4 << endl;
str4.erase(str4.begin());
cout << str4 << endl;//
str5.erase(str5.begin() + );
cout << str5<< endl;//12456789
//str6.erase(str6.begin() + 10);//这么做不行
//cout << str6 << endl;
str6.erase(str6.end() - );
cout << str6 << endl;//12345679
//str7.erase(str7.end() - 10);//这么做不行
//cout << str7 << endl;
str7.erase(str7.begin()+,str7.end()-);
str7.erase(str7.begin() + , str7.end() - );
cout << str7 << endl;//1289 删除从str7.begin()+2(包括str7.begin()+2)到str7.end() - 2(包括str7.end() - 2)的所有字符
//str8.erase(str8.begin() + 7, str8.end() - 5);//这么做不行
//cout << str8 << endl;
return ;
}

4.clear()

原型:

void clear() noexcept;

作用:
删除字符串的所有内容。

示例:

#include<iostream>
#include<string> using namespace std; int main()
{
string str("");
str.clear();
cout << str << endl;//空行
cout << str.length() << endl;//
return ;
}

5.insert()

原型:

//string (1)
basic_string& insert (size_type pos, const basic_string& str);
//substring (2)
basic_string& insert (size_type pos, const basic_string& str,
size_type subpos, size_type sublen);
//c-string (3)
basic_string& insert (size_type pos, const charT* s);
//buffer (4)
basic_string& insert (size_type pos, const charT* s, size_type n);
//fill (5)
basic_string& insert (size_type pos, size_type n, charT c);
iterator insert (const_iterator p, size_type n, charT c);
//single character (6)
iterator insert (const_iterator p, charT c);
//range (7)
template <class InputIterator>
iterator insert (iterator p, InputIterator first, InputIterator last);
//initializer list (8)
basic_string& insert (const_iterator p, initializer_list<charT> il);

说明:
1)原型(8)与list容器有关,是C++11新标准,这里赞不详述。
2)以上原型中出现的返回值和参数有iterator和InputIterator与迭代器有关,这里也暂不详述,可以将其简单地理解为指针,begin()和end()的返回值与它们匹配。

示例:

#include<iostream>
#include<string> using namespace std; int main()
{
/*
*测试basic_string& insert (size_type pos, const basic_string& str);
*/
string st1("");
//string st2("123456789");
string str1("abc");
st1.insert(, str1);
cout << st1 << endl;//123abc456789 注意是在pos所指位置前插入
//st2.insert(10, str1);//超出范围
//cout << st2 << endl;//不可以
/*
**测试basic_string& insert (size_type pos, const basic_string& str,size_type subpos, size_type sublen);
*/
string st2("");
string st3("");
string str2("abcdefg");
st2.insert(, str2, , );
cout << st2 << endl;//123cde456789
st3.insert(, str2, , );//超出范围
cout << st3 << endl;//123efg456789 可见如果超出字符串的长度,则一直到字符串的最后,不补空格
/*
**测试basic_string& insert (size_type pos, const charT* s);
*/
string st4("");
string st5("");
char* str3 = "abc";
st4.insert(, str3);
cout << st4 << endl;//123abc456789
st5.insert(, "abc");
cout << st5 << endl;//123abc456789
/*
**测试basic_string& insert (size_type pos, const charT* s, size_type n);
*/
string st6("");
string st7("");
st6.insert(, "abcdefg", );//n可以为0,为0时什么也不加 当n为负值时会出现运行时错误
cout << st6 << endl;//123abc456789
st7.insert(, "abcdefg", );//超出范围
cout << st7 << endl;//123abcdefg i n v a l i 456789 调大n值(如500)进行测试,发现中间多出来的是报错的语句和乱码,且每次运行的输出可能不一样
//CodeBlocks12.11上中间直接就是乱码
/*
**测试basic_string& insert (size_type pos, size_type n, charT c); 和 iterator insert (const_iterator p, size_type n, charT c);
*/
string st8("");
string st9("");
st8.insert(, , 'a');
cout << st8 << endl;//123aa456789
st9.insert(st9.begin() + , , 'a');
cout << st9 << endl;//123aa456789
/*
**测试iterator insert (const_iterator p, charT c);
*/
string ss1("");
ss1.insert(ss1.begin()+, 'a');//由原型知,这里不能将ss1.begin()+3改为3
cout << ss1 << endl;//123a456789
/*
**测试template <class InputIterator>
** iterator insert (iterator p, InputIterator first, InputIterator last);
*/
string ss2("");
string str4("abcdefg");
ss2.insert(ss2.begin() + , str4.begin(), str4.begin()+);//超出范围会出现运行时错误
cout << ss2 << endl;//123abc456789
return ;
}

6.append()

原型:

//string (1)
basic_string& append (const basic_string& str);
//substring (2)
basic_string& append (const basic_string& str, size_type subpos, size_type sublen);
//c-string (3)
basic_string& append (const charT* s);
//buffer (4)
basic_string& append (const charT* s, size_type n);
//fill (5)
basic_string& append (size_type n, charT c);
//range (6)
template <class InputIterator>
basic_string& append (InputIterator first, InputIterator last);
//initializer list(7)
basic_string& append (initializer_list<charT> il);

(7)不详述。
示例:

#include<iostream>
#include<string> using namespace std; int main()
{
/*
**测试basic_string& append (const basic_string& str);
*/
string st1("");
string str1("abc");
string& ss = st1.append(str1);
cout << ss << endl;//123456789abc
cout << st1 << endl;//123456789abc
/*
**测试basic_string& append (const basic_string& str, size_type subpos, size_type sublen);
*/
string st2("");
string st3("");
string str2("abcdefg");
st2.append(str2, , );
cout << st2 << endl;//123456789cde
st3.append(str2, , );//超出范围
cout << st3 << endl;//123456789defg 当用数字表示范围时,若超出范围,则直到字符串的结尾,不会补空格,也不会出现运行时错误
cout << st3.length() << endl;//13 尽管如此,在实际编程时,也必须保证不超范围
/*
**测试basic_string& append (const charT* s);
*/
string st4("");
st4.append("abc");
cout << st4 << endl;//123456789abc
/*
**测试basic_string& append (const charT* s, size_type n);
*/
string st5("");
st5.append("abc", );//超出范围
cout << st5 << endl;//123456789abc+乱码
/*
**测试basic_string& append (size_type n, charT c);
*/
string st6("");
st6.append(, 0x41);//可以用16进制的ASCII码
cout << st6 << endl;//123456789AAA
/*
**测试template <class InputIterator>
**basic_string& append (InputIterator first, InputIterator last);
*/
/*
string st7("123456789");
string str3("abcdefg");
st6.append(str3.begin() + 2, str3.begin() + 10);//超出范围
cout << st7 << endl;//当使用迭代器时,若超出范围,则会出现运行时错误
*/
return ;
}

7.replace()

原型:

//string (1)
basic_string& replace (size_type pos, size_type len, const basic_string& str);
basic_string& replace (const_iterator i1, const_iterator i2, const basic_string& str);
//substring (2)
basic_string& replace (size_type pos, size_type len, const basic_string& str,
size_type subpos, size_type sublen);
//c-string (3)
basic_string& replace (size_type pos, size_type len, const charT* s);
basic_string& replace (const_iterator i1, const_iterator i2, const charT* s);
//buffer (4)
basic_string& replace (size_type pos, size_type len, const charT* s, size_type n);
basic_string& replace (const_iterator i1, const_iterator i2, const charT* s, size_type n);
//fill (5)
basic_string& replace (size_type pos, size_type len, size_type n, charT c);
basic_string& replace (const_iterator i1, const_iterator i2, size_type n, charT c);
//range (6)
template <class InputIterator>
basic_string& replace (const_iterator i1, const_iterator i2,
InputIterator first, InputIterator last);
//initializer list (7)
basic_string& replace (const_iterator i1, const_iterator i2, initializer_list<charT> il);

(7)不详述
示例:(这里仅给出部分原型的测试,其它的读者可参照前面几个函数的实例自行测试)

#include<iostream>
#include<string> using namespace std; int main()
{
/*
**测试basic_string& replace (size_type pos, size_type len, const basic_string& str);
*/
string st1("");
string str1("abcde");
string str2("ab");
st1.replace(, , str1);//将位置2开始的3个字符(345)换成abcde
cout << st1 << endl;//12abcde6789
string st2("");
st2.replace(, , str1);
cout << st2 << endl;//1abcde9
string st3("");
st3.replace(, , str2);//超出范围
cout << st3 << endl;//123456ab
/*
**测试basic_string& replace (const_iterator i1, const_iterator i2, const basic_string& str);
*/
/*string st4("123456789");
st4.replace(st4.begin() + 8, st4.begin() + 10, str1); //迭代器超范围,出现运行时错误
cout << st4 << endl;*/
/*
**测试basic_string& replace (size_type pos, size_type len, const charT* s, size_type n);
*/
string st5("");
st5.replace(, , "abcdefg", );
cout << st5 << endl;//12abcde6789
string st6("");
st6.replace(, , "abc", );//超出范围
cout << st6 << endl;//12abc+乱码+6789 对于char*类型,若超出范围,就会出现乱码
return ;
}

以上各函数的原型及参数的意义大同小异,读者可以触类旁通。现结合以上各示例,对“超出范围”这一特殊情况给出一般性的规律总结:
1.对于string类型,用数字表示范围,超出时,自动截止到字符串的末尾,不会补空格,不会有乱码,也不会出现运行时错误。
2.对于string类型,用迭代器表示范围,超出时,出现运行时错误。
3.对于char*类型,用数字表示范围(只能用数字表示,char*是基本类型,没有迭代器),超出时,会出现乱码。

C++string中有关字符串内容修改和替换的函数浅析的更多相关文章

  1. Android逆向之旅---Android应用的汉化功能(修改SO中的字符串内容)

    一.前言 今天我们继续来讲述逆向的知识,今天我们来讲什么呢?我们在前一篇文章中介绍了关于SO文件的格式,今天我们继续这个话题来看看如何修改SO文件中的内容,看一下我们研究的主题: 需求:想汉化一个Ap ...

  2. String中对字符串进行操作的一些方法

    1.substring 作用:根据字符串下标进行截取 public class StrTest { public static void main(String[] args) { String a ...

  3. 从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接

    长久以来,我们被教导字符串的连接最好用StringBuffer.StringBuilder,但是我们却不知道这两者之间的区别.跟字符串相关的一些方法中总是有CharSequence.StringBuf ...

  4. vim /vi中对字符串的查找并替换

    vi/vim 中可以使用 :s 命令来替换字符串.该命令有很多种不同细节使用方法,可以实现复杂的功能,记录几种在此,方便以后查询.    :s/vivian/sky/ 替换当前行第一个 vivian ...

  5. 092、Java中String类之字符串内容比较

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  6. Day_14【IO流】扩展案例3_对文本文件中的字符串内容进行反转

    分析以下需求,并用代码实现 项目根路径下有text.txt文件,内容如下 我爱黑马 123456 利用IO流的知识读取text.txt文件的内容反转后写入text.txt文件中 654321 马黑爱我 ...

  7. 把ArrayList集合中的字符串内容写到文本文件中

    list列表数据导出到指定路径文本文档中 public  String getSDCardPath() { String sdCard = Environment.getExternalStorage ...

  8. 如何在idea中设置 jsp 内容修改以后,立即生效而不用重新启动服务?

    点击 run---->edit configuration--->

  9. string中c_str()、data()、copy(p,n)函数的用法

    标准库的string类提供了3个成员函数来从一个string得到c类型的字符数组:c_str().data().copy(p,n). 1. c_str():生成一个const char*指针,指向以空 ...

随机推荐

  1. Kmeans方法

    基本Kmeans算法介绍及其实现 http://blog.csdn.net/qll125596718/article/details/8243404/ kmeans++ http://www.52ml ...

  2. ubuntu下neural-style-master的demo

    1.Installing Torch 参考官网:http://torch.ch/docs/getting-started.html git clone https://github.com/torch ...

  3. Choose Concurrency-Friendly Data Structures

    What is a high-performance data structure? To answer that question, we're used to applying normal co ...

  4. 面向系统管理员的10款Linux GUI工具 (转自51cto)

    如果你是名系统管理员,现已到了Linux非知道不可的地步.如果你在更庞大的环境下工作,更是如此.许多企业组织已迁离了一切都借助点击式GUI来管理的Windows.幸好,Linux也有许多GUI工具可以 ...

  5. Jquery 在页面加载后执行的几种方式

    1.$(function(){  $("#a").click(function(){  //adding your code here  }); }); 2.$(document) ...

  6. php mysql_num_rows() 与 mysql_affected_rows()

    mysql_num_rows(data) 函数返回结果集中行的数目. data 结果集.该结果集从 mysql_query() 的调用中得到. 此命令仅对 SELECT 语句有效.要取得被 INSER ...

  7. C#编程利器之二:结构与枚举(Structure and enumeration)【转】

    C#编程利器之二:结构与枚举(Structure and enumeration) 在上一篇文章中,介绍了类如何封装程序中的对象.而实际中,出了类可以封装对象外,结构和枚举也可以封装一些对象,本文将着 ...

  8. Apache Benchmark测试工具

    ab命令-- ab -c 数字(连接数) -t 数字(连接时间) http://网站:端口/路径 ab -n 数字(点击数) -c 数字(连接数) -k(同时点击) http://网站:端口/路径

  9. tomcat 设置集群

    本文介绍的是使用tomcat内置的集群功能.跟官方文档的区别是没有使用广播,而是使用了static membership的方式. 需要修改server.xml 放在哪个元素下来的,是Host还是啥记不 ...

  10. thttpd和cgilua安装与运行流程分析

    安装 参考如下博文安装thttpd软件 http://blog.csdn.net/21aspnet/article/details/7045845 http://blog.csdn.net/drago ...