1.assign()

原型:

//string(1)basic_string&assign(constbasic_string&str);//substring(2)basic_string&assign(constbasic_string&str,size_typesubpos,size_typesublen);//c-string(3)basic_string&assign(constcharT*s);//buffer(4)basic_string&assign(constcharT*s,size_typen);//ill(5)basic_string&assign(size_typen,charTc);//range(6)template<classInputIterator>basic_string&assign(InputIteratorfirst,InputIteratorlast);

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

示例:

#include<iostream>#include<string>usingnamespacestd;intmain(){stringstr1("123456");stringstr="123456789";char*str2="abcdef";str.assign(str1);cout<<str<<endl;//123456可见执行assign()后,str将被重写str.assign(str1,2,3);cout<<str<<endl;//345从位置2开始的3个字符str.assign(str1,1,20);//超出范围cout<<str<<endl;//23456cout<<str.length()<<endl;//5可见没有空格str.assign(str1,2,str1.npos);//后面介绍nposcout<<str<<endl;//3456从位置2到末尾的字符给strstr.assign(5,'X');cout<<str<<endl;//XXXXXstr.assign(str1.begin(),str1.end()-1);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()+2,str1.end()-3);//前后指向同一字符(3),这样可以cout<<str<<endl;//3str.assign(str1.begin()+2,str1.end()-4);//这个却可以cout<<str<<endl;//空行cout<<str.length()<<endl;//0str.assign("abcdefg",6);cout<<str<<endl;//abcdef将abcdefg的前6个字符给strstr.assign("abcdefg",20);//超出范围cout<<str<<endl;//abcdefg+乱码cout<<str.length()<<endl;//10说明将"abcdefg+3个空格"给了strstr.assign(3,0x41);cout<<str<<endl;//AAA可以使用16进制的ASCII码0x41换成10进制是65,是A的ASCII码str.assign(str2);cout<<str<<endl;//abcdefstr.assign(str2,2,3);cout<<str<<endl;//cde对char*型也可以return0;}

以上代码中有一句
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>usingnamespacestd;intmain(){stringstr1="123456789";cout<<str1.npos<<endl;//4294967295cout<<(str1.npos==-1)<<endl;//1cout<<str1.max_size()<<endl;//42949672941073741820(=2^30-4)return0;}

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

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

//initializerlist(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_typepos=0,size_typelen=npos);//character(2)iteratorerase(iteratorp);//range(3)iteratorerase(iteratorfirst,iteratorlast);

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

示例:

#include<iostream>#include<string>usingnamespacestd;intmain(){stringstr1("123456789");stringstr2("123456789");stringstr3("123456789");stringstr4("123456789");stringstr5("123456789");stringstr6("123456789");stringstr7("123456789");stringstr8("123456789");str1.erase(2,3);cout<<str1<<endl;//126789str2.erase(2,10);cout<<endl;//空行str3.erase(7);//注意这里的参数值不能超过str3.length(),否则会出现运行时错误等于是输出空行,相当于删除'\0'及其后面的(当然后面什么也没有,//因为'\0'已经是最后一个)cout<<str3<<endl;//1234567当省略第2个参数时,删除第1个参数所指位置起(即包括该位置)的所有字符//str4.erase(10,5);//这么做不行//cout<<str4<<endl;str4.erase(str4.begin());cout<<str4<<endl;//23456789str5.erase(str5.begin()+2);cout<<str5<<endl;//12456789//str6.erase(str6.begin()+10);//这么做不行//cout<<str6<<endl;str6.erase(str6.end()-2);cout<<str6<<endl;//12345679//str7.erase(str7.end()-10);//这么做不行//cout<<str7<<endl;str7.erase(str7.begin()+2,str7.end()-2);str7.erase(str7.begin()+2,str7.end()-2);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;return0;}

4.clear()

原型:

voidclear()noexcept;

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

示例:

#include<iostream>#include<string>usingnamespacestd;intmain(){stringstr("123456789");str.clear();cout<<str<<endl;//空行cout<<str.length()<<endl;//0return0;}

5.insert()

原型:

//string(1)basic_string&insert(size_typepos,constbasic_string&str);//substring(2)basic_string&insert(size_typepos,constbasic_string&str,size_typesubpos,size_typesublen);//c-string(3)basic_string&insert(size_typepos,constcharT*s);//buffer(4)basic_string&insert(size_typepos,constcharT*s,size_typen);//fill(5)basic_string&insert(size_typepos,size_typen,charTc);iteratorinsert(const_iteratorp,size_typen,charTc);//singlecharacter(6)iteratorinsert(const_iteratorp,charTc);//range(7)template<classInputIterator>iteratorinsert(iteratorp,InputIteratorfirst,InputIteratorlast);//initializerlist(8)basic_string&insert(const_iteratorp,initializer_list<charT>il);

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

示例:

#include<iostream>#include<string>usingnamespacestd;intmain(){/**测试basic_string&insert(size_typepos,constbasic_string&str);*/stringst1("123456789");//stringst2("123456789");stringstr1("abc");st1.insert(3,str1);cout<<st1<<endl;//123abc456789注意是在pos所指位置前插入//st2.insert(10,str1);//超出范围//cout<<st2<<endl;//不可以/***测试basic_string&insert(size_typepos,constbasic_string&str,size_typesubpos,size_typesublen);*/stringst2("123456789");stringst3("123456789");stringstr2("abcdefg");st2.insert(3,str2,2,3);cout<<st2<<endl;//123cde456789st3.insert(3,str2,4,9);//超出范围cout<<st3<<endl;//123efg456789可见如果超出字符串的长度,则一直到字符串的最后,不补空格/***测试basic_string&insert(size_typepos,constcharT*s);*/stringst4("123456789");stringst5("123456789");char*str3="abc";st4.insert(3,str3);cout<<st4<<endl;//123abc456789st5.insert(3,"abc");cout<<st5<<endl;//123abc456789/***测试basic_string&insert(size_typepos,constcharT*s,size_typen);*/stringst6("123456789");stringst7("123456789");st6.insert(3,"abcdefg",3);//n可以为0,为0时什么也不加当n为负值时会出现运行时错误cout<<st6<<endl;//123abc456789st7.insert(3,"abcdefg",20);//超出范围cout<<st7<<endl;//123abcdefginvali456789调大n值(如500)进行测试,发现中间多出来的是报错的语句和乱码,且每次运行的输出可能不一样//CodeBlocks12.11上中间直接就是乱码/***测试basic_string&insert(size_typepos,size_typen,charTc);和iteratorinsert(const_iteratorp,size_typen,charTc);*/stringst8("123456789");stringst9("123456789");st8.insert(3,2,'a');cout<<st8<<endl;//123aa456789st9.insert(st9.begin()+3,2,'a');cout<<st9<<endl;//123aa456789/***测试iteratorinsert(const_iteratorp,charTc);*/stringss1("123456789");ss1.insert(ss1.begin()+3,'a');//由原型知,这里不能将ss1.begin()+3改为3cout<<ss1<<endl;//123a456789/***测试template<classInputIterator>**iteratorinsert(iteratorp,InputIteratorfirst,InputIteratorlast);*/stringss2("123456789");stringstr4("abcdefg");ss2.insert(ss2.begin()+3,str4.begin(),str4.begin()+3);//超出范围会出现运行时错误cout<<ss2<<endl;//123abc456789return0;}

6.append()

原型:

//string(1)basic_string&append(constbasic_string&str);//substring(2)basic_string&append(constbasic_string&str,size_typesubpos,size_typesublen);//c-string(3)basic_string&append(constcharT*s);//buffer(4)basic_string&append(constcharT*s,size_typen);//fill(5)basic_string&append(size_typen,charTc);//range(6)template<classInputIterator>basic_string&append(InputIteratorfirst,InputIteratorlast);//initializerlist(7)basic_string&append(initializer_list<charT>il);

(7)不详述。
示例:

#include<iostream>#include<string>usingnamespacestd;intmain(){/***测试basic_string&append(constbasic_string&str);*/stringst1("123456789");stringstr1("abc");string&ss=st1.append(str1);cout<<ss<<endl;//123456789abccout<<st1<<endl;//123456789abc/***测试basic_string&append(constbasic_string&str,size_typesubpos,size_typesublen);*/stringst2("123456789");stringst3("123456789");stringstr2("abcdefg");st2.append(str2,2,3);cout<<st2<<endl;//123456789cdest3.append(str2,3,20);//超出范围cout<<st3<<endl;//123456789defg当用数字表示范围时,若超出范围,则直到字符串的结尾,不会补空格,也不会出现运行时错误cout<<st3.length()<<endl;//13尽管如此,在实际编程时,也必须保证不超范围/***测试basic_string&append(constcharT*s);*/stringst4("123456789");st4.append("abc");cout<<st4<<endl;//123456789abc/***测试basic_string&append(constcharT*s,size_typen);*/stringst5("123456789");st5.append("abc",5);//超出范围cout<<st5<<endl;//123456789abc+乱码/***测试basic_string&append(size_typen,charTc);*/stringst6("123456789");st6.append(3,0x41);//可以用16进制的ASCII码cout<<st6<<endl;//123456789AAA/***测试template<classInputIterator>**basic_string&append(InputIteratorfirst,InputIteratorlast);*//*stringst7("123456789");stringstr3("abcdefg");st6.append(str3.begin()+2,str3.begin()+10);//超出范围cout<<st7<<endl;//当使用迭代器时,若超出范围,则会出现运行时错误*/return0;}

7.replace()

原型:

//string(1)basic_string&replace(size_typepos,size_typelen,constbasic_string&str);basic_string&replace(const_iteratori1,const_iteratori2,constbasic_string&str);//substring(2)basic_string&replace(size_typepos,size_typelen,constbasic_string&str,size_typesubpos,size_typesublen);//c-string(3)basic_string&replace(size_typepos,size_typelen,constcharT*s);basic_string&replace(const_iteratori1,const_iteratori2,constcharT*s);//buffer(4)basic_string&replace(size_typepos,size_typelen,constcharT*s,size_typen);basic_string&replace(const_iteratori1,const_iteratori2,constcharT*s,size_typen);//fill(5)basic_string&replace(size_typepos,size_typelen,size_typen,charTc);basic_string&replace(const_iteratori1,const_iteratori2,size_typen,charTc);//range(6)template<classInputIterator>basic_string&replace(const_iteratori1,const_iteratori2,InputIteratorfirst,InputIteratorlast);//initializerlist(7)basic_string&replace(const_iteratori1,const_iteratori2,initializer_list<charT>il);

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

#include<iostream>#include<string>usingnamespacestd;intmain(){/***测试basic_string&replace(size_typepos,size_typelen,constbasic_string&str);*/stringst1("123456789");stringstr1("abcde");stringstr2("ab");st1.replace(2,3,str1);//将位置2开始的3个字符(345)换成abcdecout<<st1<<endl;//12abcde6789stringst2("123456789");st2.replace(1,7,str1);cout<<st2<<endl;//1abcde9stringst3("123456789");st3.replace(6,9,str2);//超出范围cout<<st3<<endl;//123456ab/***测试basic_string&replace(const_iteratori1,const_iteratori2,constbasic_string&str);*//*stringst4("123456789");st4.replace(st4.begin()+8,st4.begin()+10,str1);//迭代器超范围,出现运行时错误cout<<st4<<endl;*//***测试basic_string&replace(size_typepos,size_typelen,constcharT*s,size_typen);*/stringst5("123456789");st5.replace(2,3,"abcdefg",5);cout<<st5<<endl;//12abcde6789stringst6("123456789");st6.replace(2,3,"abc",20);//超出范围cout<<st6<<endl;//12abc+乱码+6789对于char*类型,若超出范围,就会出现乱码return0;}

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