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. ready是先执行的,load后执行,DOM文档的加载步骤

    在jq中在文档载入完毕后有这几种方式去执行指定函数: $(document).ready(function() { // ...代码... }); //document ready 简写 $(func ...

  2. Bootstrap css栅格 + 网页中插入代码+css表格

    设计达人 http://www.shejidaren.com/30-minimal-app-icons.html CSS栅格: <!DOCTYPE html> <html lang= ...

  3. JSP Standard Tag Library JSP标准标签库

    了解了基本的标签的底层实现,可以看系统定义的强大的标准标签 1.首先引入两个jar包 2.基本语法 <%@ taglib prefix="c" uri="http: ...

  4. python 正则使用笔记

    python正则使用笔记 def remove_br(content): """去除两边换行符""" content = content.r ...

  5. python学习道路(day1note)(变量,注释,用户输入,格式化输出,if,while,for循环并扩展练习)

    python是一门动态解释性的强类型定义语言,其应用范围非常之广 1:进入python语言 #!/usr/bin/env python #_*_coding:utf-8_*_ print(" ...

  6. ArcGIS Server,4000端口被占用

    server使用的端口:http://resources.arcgis.com/zh-cn/help/main/10.2/index.html#//015400000537000000 cmd 输入命 ...

  7. PHP:array_chunk()数组分割

    array_chunk(); 作用:把一个数组分割为新的数组块 用法: 实例:把数组分割为带有两个元素的数组块 $cars=array("Volvo","BMW" ...

  8. Fixing “WARNING: UNPROTECTED PRIVATE KEY FILE!” on Linux

    If you are getting this error then you probably reset the permissions on your hidden .ssh directory ...

  9. 【转】给npm设置代理

    可以运行如下两句命令设置代理,注意代理的地址改为自己实际可用的代理. npm config set proxy=http://127.0.0.1:8087 npm config set registr ...

  10. 分类指标准确率(Precision)和正确率(Accuracy)的区别

    http://www.cnblogs.com/fengfenggirl/p/classification_evaluate.html 一.引言 分类算法有很多,不同分类算法又用很多不同的变种.不同的分 ...