C 中STRING的详解 WOLD
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
string类解说
注:本文由018整理,部分代码、资料出处与作者不详,代码已经VC++6.0编译通过。
如要转载本文,请注明出处:018工作室作者:018
标准C++库提供了一个强大的C++程序string类。
String类是基于basic_string类模板的。
basic_string类模板:
【代码】:
template<class E,
class T=char traits<E>,
class A=allocate<T>>
class basic_string{
public:
typeset T traits type;
typeset A allocator_type;
typeset T::char_type char_type;
typeset A::size_type size_type;
typeset A::difference_type difference_type;
typeset A:pointer pointer;
typeset A::const_pointer const_pointer;
typeset A::reference reference;
typeset A::const_reference const_reference;
typeset A::value_type value_type;
typeset T0iterator;
typeset T1const_iterator;
typeset reverse_iterator<iterator,value_type,
reference,pointer,difference_type>
reverse_iterator;
typeset reverse_iterator<const_iterator,value_type,
const_reference,const_pointer,difference_type>
const_reverse_iterator;
static const size_type npos=-1;
explicit basic_string(const A&al=A());
basic_string(const basic_string&rhs);
basic_string(const basic_string&rhs,size_type pos,size_type n,
const A&al=A());
basic_string(const E*s,size_type n,const A&al=A());
basic_string(const E*s,const A&al=A());
basic_string(size_type n,E c,const A&al=A());
basic_string(const_iterator first,const_iterator last,
const A&al=A());
basic_string&operator=(const basic_string&rhs);
basic_string&operator=(const E*s);
basic_string&operator=(E c);
iterator begin();
const_iterator begin()const;
iterator end();
const_iterator end()const;
reverse_iterator rbegin();
const_reverse_iterator rbegin()const;
reverse_iterator rend();
const_reverse_iterator rend()const;
const_reference at(size_type pos)const;
reference at(size_type pos);
const_reference operator[](size_type pos)const;
reference operator[](size_type pos);
const E*c_str()const;
const E*data()const;
size_type length()const;
size_type size()const;
size_type max_size()const;
void resize(size_type n,E c=E());
size_type capacity()const;
void reserve(size_type n=0);
bool empty()const;
basic_string&operator+=(const basic_string&rhs);
basic_string&operator+=(const E*s);
basic_string&operator+=(E c);
basic_string&append(const basic_string&str);
basic_string&append(const basic_string&str,
size_type pos,size_type n);
basic_string&append(const E*s,size_type n);
basic_string&append(const E*s);
basic_string&append(size_type n,E c);
basic_string&append(const_iterator first,const_iterator last); basic_string&assign(const basic_string&str);
basic_string&assign(const basic_string&str,
size_type pos,size_type n);
basic_string&assign(const E*s,size_type n);
basic_string&assign(const E*s);
basic_string&assign(size_type n,E c);
basic_string&assign(const_iterator first,const_iterator last); basic_string&insert(size_type p0,
const basic_string&str);
basic_string&insert(size_type p0,
const basic_string&str,size_type pos,size_type n); basic_string&insert(size_type p0,
const E*s,size_type n);
basic_string&insert(size_type p0,const E*s);
basic_string&insert(size_type p0,size_type n,E c); iterator insert(iterator it,E c);
void insert(iterator it,size_type n,E c);
void insert(iterator it,
const_iterator first,const_iterator last);
basic_string&erase(size_type p0=0,size_type n=npos); iterator erase(iterator it);
iterator erase(iterator first,iterator last);
basic_string&replace(size_type p0,size_type n0,
const basic_string&str);
basic_string&replace(size_type p0,size_type n0,
const basic_string&str,size_type pos,size_type n); basic_string&replace(size_type p0,size_type n0,
const E*s,size_type n);
basic_string&replace(size_type p0,size_type n0,
const E*s);
basic_string&replace(size_type p0,size_type n0,
size_type n,E c);
basic_string&replace(iterator first0,iterator last0,
const basic_string&str);
basic_string&replace(iterator first0,iterator last0,
const E*s,size_type n);
basic_string&replace(iterator first0,iterator last0,
const E*s);
basic_string&replace(iterator first0,iterator last0,
size_type n,E c);
basic_string&replace(iterator first0,iterator last0,
const_iterator first,const_iterator last);
size_type copy(E*s,size_type n,size_type pos=0)const; void swap(basic_string&str);
size_type find(const basic_string&str,
size_type pos=0)const;
size_type find(const E*s,size_type pos,size_type n)const; size_type find(const E*s,size_type pos=0)const;
size_type find(E c,size_type pos=0)const;
size_type rfind(const basic_string&str,
size_type pos=npos)const;
size_type rfind(const E*s,size_type pos,
size_type n=npos)const;
size_type rfind(const E*s,size_type pos=npos)const; size_type rfind(E c,size_type pos=npos)const;
size_type find_first_of(const basic_string&str,
size_type pos=0)const;
size_type find_first_of(const E*s,size_type pos,
size_type n)const;
size_type find_first_of(const E*s,size_type pos=0)const;
size_type find_first_of(E c,size_type pos=0)const;
size_type find_last_of(const basic_string&str,
size_type pos=npos)const;
size_type find_last_of(const E*s,size_type pos,
size_type n=npos)con/t;
size_type find_last_of(const E*s,size_type pos=npos)const;
size_type find_last_of(E c,size_type pos=npos)const;
size_type find_first_not_of(const basic_string&str,
size_type pos=0)const;
size_type find_first_not_of(const E*s,size_type pos,
size_type n)const;
size_type find_first_not_of(const E*s,size_type pos=0)const;
size_type find_first_not_of(E c,size_type pos=0)const;
size_type find_last_not_of(const basic_string&str,
size_type pos=npos)const;
size_type find_last_not_of(const E*s,size_type pos,
size_type n)const;
size_type find_last_not_of(const E*s,
size_type pos=npos)const;
size_type find_last_not_of(E c,size_type pos=npos)const;
basic_string substr(size_type pos=0,size_type n=npos)const;
int compare(const basic_string&str)const;
int compare(size_type p0,size_type n0,
const basic_string&str);
int compare(size_type p0,size_type n0,
const basic_string&str,size_type pos,size_type n);
int compare(const E*s)const;
int compare(size_type p0,size_type n0,
const E*s)const;
int compare(size_type p0,size_type n0,
const E*s,size_type pos)const;
A get_allocator()const;
protected:
A allocate;
};
标准C++声明了基于basic_string类的两种类型定义,分别是string安定wstring:typeset basic_string<char,char traits<char>,allocate<char>>string;
typeset basic_string<wchar_t,char traits<wchar_t>,allocate<wchar_t>>wstring;
而basic_string在<xstring>头文件中定义。
一、string类的构造函数:
string();//默认构造函数,创建一个空串
如:string str;
string(const char*s);//用C-串s初始化
如:1)string str("const char");//str=”const char”
2)char*chp="const char";
string str(chp);//str=”const char”
3)char ch[]="const char";
string str(ch);//str=”const char”
string(int n,char c);//用n个字符c初始化
如:string str(5,’a’);//str=”aaaaa”
string(const string&str,size_t pos,size_t n);//取str串从pos开始往后的n个字符来初始化
如:string strdst(”abcde”);
string strscr(strdst,2,3);//strscr=”cde”
string(const char*s,size_t n);//用C-串s的前n个字符来初始化
如:char*strp="abcde";
string str(strp,2);//strscr=”ab”
string(const string&str);//用str串来初始化
如:string strdst("abcde");
ing strscr(strdst);//strscr=”abcde”
此外,string类还支持复制构造函数,string s2="hello";是正确的写法。
当构造的string 太长而无法表达时会抛出length_error异常。
二、string类的容器
allocate分配器
allocator_type The type is a synonym for the template parameter A.
iterator访回string的迭代器
const_iterator访回string的常量迭代器
pointer指向T(char)的指针
const_pointer指向T(char)的常量指针
const_reference T(char)的常量引用
reference T(char)的引用
const_reverse_iterator访回string的方向常量迭代器
reverse_iterator访回string的方向迭代器
difference_type int类型
size_type unsigned int类型
traits_type The type is a synonym for the template parameter T.
value_type对象类型T(char)
三、string类的字符操作:
string&operator+=(const char*s);//追加C-串s
如:string str("string");
str+="+=C-strings";//str=”string+=C-strings”
string&operator+=(const string&str);//追加str串
如:string str1("string");
string str2("+=string");
str+=str2;//str=”string+=string”
string&operator+=(char c);//追加字符c
如:string str("string");
str+=’+’;//str=”string+”
string&operator=(const char*s);//用C-串s赋值
如:string str=”string”;
string&operator=(const string&str);//用str串赋值
如:string str1,str2(“strdst”);
str1=str2;//str1=”strdst”
string&operator=(char c);//用字符c赋值
如:stirng str1;
str1=’s’;
const_reference operator[](size_type pos)const;|reference operator[](size_t ype pos);//返回当前字符串中第pos个字符的位置,当越界,则该动作无效。
如:string(“string”);
string::reference s=str1[1];//s=’t’
const_reference at(size_type pos)const;|reference at(size_type pos);//返回当前字符串中第pos个字符的位置,当越界时会抛出out_of_range异常。
如:string(“string”);
string::reference s=str1.at(1);//s=’t’
const char*data()const;//以数组方式返回string的内容,其大小为size()的返回值,结尾并没有\0字符。
如:string str(“str\0ing”);
str.data();//返回指向”str”的指针
const char*c_str()const;//返回一个以\0结尾的C-串。
如:string str(“str\0ing”);
str.c_str();//返回指向”str\0”的指针
size_type copy(char*s,size_type n,size_type pos=0)const;//把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目如:string str("string");
char*ch=new char;
int n;
n=str.copy(ch,3,5);//ch=”g”,n=1
n=str.copy(ch,3,2);//ch=”rin”,n=3
四、string类的特性描述:
size_type capacity()const;//返回当前容量在它已经分配的内存中可以容纳多少元素。
(即string中不必增加内存即可存放的元素个数)
void reserve(size_type n);//强制容器把它的容量改为至少n
size_type max_size()const;//返回string对象中可存放的最大字符串的长度
size_type size()const;//返回当前字符串的大小
void resize(size_type n,char c=char());//把字符串当前大小置为n,并用字符c填充不足的部分
size_type length()const;//返回当前字符串的长度,跟size()相识。
bool empty()const;//当前字符串是否为空
关于STL容器,最神奇的事情之一是只要不超过它们的最大大小(通过成员max_size 查看),它们就可以自动增长到足以容纳你放进去的数据。
对于vector和string,只要需要更多空间,就以realloc等价的思想来增长。
这个类似于realloc的操作有四个部分:
1、分配新的内存块,它有容器目前容量的几倍。
在大部分实现中,vector和string
的容量每次以2为因数增长。
也就是说,当容器必须扩展时,它们的容量每次翻倍。
2、把所有元素从容器的旧内存拷贝到它的新内存。
3、销毁旧内存中的对象。
4、回收旧内存。
给了所有的分配,回收,拷贝和析构,你就应该知道那些步骤都很昂贵。
当每次这些步骤发生时,所有指向vector或string中的迭代器、指针和引用都会失效时。
这意味着简单地把一个元素插入vector或string的动作也可能因为需要更新其他使用了指向vector或string中的迭代器、指针或引用的数据结构而膨胀。
reserve成员函数允许你最小化必须进行的重新分配的次数,因而可以避免真分配的开销和迭代器/指针/引用失效。
但在我解释reserve为什么可以那么做之前,让我简要介绍有时候令人困惑的四个相关成员函数。
在标准容器中,只有vector和string提供了所有这些函数。
size():容器中有多少元素。
它没有告诉你容器为它容纳的元素分配了多少内存。
capacity():容器在它已经分配的内存中可以容纳多少元素。
那是容器在那块内存中总共可以容纳多少元素,而不是还可以容纳多少元素。
如果你想知道一个vector 或string中有多少没有被占用的内存,你必须从capacity()中减去size()。
如果size 和capacity返回同样的值,容器中就没有剩余空间了,而下一次插入(通过insert 或push_back等)会引发上面的重新分配步骤。
resize(size_type n)强制把容器改为容纳n个元素。
调用resize之后,size将会返回n。
如果n小于当前大小,容器尾部的元素会被销毁。
如果n大于当前大小,新默认构造的元素会添加到容器尾部。
如果n大于当前容量,在元素加入之前会发生重新分配。
reserve(size_type n)强制容器把它的容量改为至少n,提供的n不小于当前大小。
这一般强迫进行一次重新分配,因为容量需要增加。
(如果n小于当前容量,vector 忽略它,这个调用什么都不做,string可能把它的容量减少为size()和n中大的数,但string的元素大小没有改变。
在《Effective STL》作者的经验中,使用reserve来从一个string中修整多余容量一般不如使用“交换技巧”,那是《Effective STL》条款17的主题。
)
这个简介明确表示了只要有元素需要插入而且容器的容量不足时就会发生重新分配(包括它们维护的原始内存分配和回收,对象的拷贝和析构和迭代器、指针和引用的失效)。
所以,避免重新分配的关键是使用reserve尽快把容器的容量设置为足够大,最好在容器被构造之后立刻进行。
例如,假定你想建立一个容纳1-1000个字符的string。
没有使用reserve,你可以像这样来
做:
string str;
for(int i=1;i<=1000;++i)
str+=char(i);
在大多数STL实现中,这段代码在循环过程中将会导致2到10次重新分配。
(10这个数没什么奇怪的。
记住string在重新分配发生时一般把容量翻倍,而1000约等于210。
)
把代码改为使用reserve,我们得到这个:
string str;
str.reserve(1000);
for(int i=1;i<=1000;++i)
str+=char(i);
这在循环中不会发生重新分配。
在大小和容量之间的关系让我们可以预言什么时候插入将引起vector或string执行重新分配,而且,可以预言什么时候插入会使指向容器中的迭代器、指针和引用失效。
例如,给出这段代码,
string str;
...
if(str.size()<str.capacity())
{
str+=’z’;
}
operator+=的调用不会使指向这个string中的迭代器、指针或引用失效,因为string的容量保证大于它的大小。
如果不是执行operator+=,代码在string的任意位置进行一个insert,我们仍然可以保证在插入期间没有发生重新分配,但是,与伴随string插入时迭代器失效的一般规则一致,所有从插入位置到string结尾的迭代器/指针/引用将失效。
回到本条款的主旨,通常有两情况使用reserve来避免不必要的重新分配。
第一个可用的情况是当你确切或者大约知道有多少元素将最后出现在容器中。
那样的话,就像上面的string代码,你只是提前reserve适当数量的空间。
第二种情况是保留你可能需要的最大的空间,然后,一旦你添加完全部数据,修整掉任何多余的容量。
修整部分不难,但是我将不这里显示它,因为对它有一个技巧。
要学习这个技巧,请查看《Effective STL》条款17。
参考资料:《Effective STL》条款14、使用reserve来避免不必要的重新分配
五、string类的赋值:
string&operator=(const char*s);//见三、string类的字符操作
string&operator=(const string&str);//见三、string类的字符操作
string&operator=(char c);//见三、string类的字符操作
string&assign(const char*s);//用C-串s赋值,同operator=(const char*s)如:string str;
str.assign(”string”);//str=”string”
string&assign(const char*s,size_type n);//用C-串s开始的n个字符赋值如:string str;
str.assign(“string”,3);//str=”str”
string&assign(const string&str);//把字符串str赋给当前字符串,同operator=(c onst string&str)
如:string str1,str2(“strdst”);
str1.assign(”strdst”);//str1=”strdst”
string&assign(size_type n,char c);//用n个字符c赋值给当前字符串如:string str;
str.assign(3,’a’);//str=”aaa”
string&assign(const string&str,size_type pos,size_type n);//把字符串str中从pos开始的n个字符赋给当前字符串
如:string str1,str2(“strdst”);
str1.assign(str2,0,3);//str1=”str”
string&assign(const_iterator first,const_iterator last);//把[first,last)迭代器之间的部分赋给字符串
如:string str1,str2("string");
string::iterator it1=str2.begin(),it2=str2.end();
str1.assign(++it1,--it2);//str1=”trin”
六、string类的连接:
string&operator+=(const char*s);//见三、string类的字符操作
string&operator+=(const string&str);//见三、string类的字符操作
string&operator+=(char c);//见三、string类的字符操作
string&append(const char*s);//把C-串s连接到当前字符串结尾,同operator+= (const char*s)
如:string str=”string”;
str.append("append");//str=”string append”
string&append(const char*s,size_type n);//把C-串s的前n个字符连接到当前字符串结尾
如:string str=”string”;
str.append("append string",7);//str=”string append”
string&append(const string&str);//把字符串str连接到当前字符串结尾,同oper ator+=(const string&str)
如:string str1,str2(“append”);
str1.append(str2);//str1=”string append”
string&append(const string&str,size_type pos,size_type n);//把字符串str中从pos开始的n个字符连接到当前字符串的结尾
如:string str1=”str”,str2=”ingstr”;
str1.append(str2,0,3);//str1=”string”
string&append(size_type n,char c);//在当前字符串结尾添加n个字符c 如:string str=”str”;
str.append(3,’s’);//str=”strsss”
string&append(const_iterator first,const_iterator last);//把[first,last)迭代器之间的部分连接到当前字符串的结尾
如:string str1(“strsrc”),str2("strdst”);
string::iterator it1=str2.begin(),it2=str2.end();
str1.append(++it1,--it2);//str1=”strsrctrds”
七、string类的比较:
bool operator==(const string&str1,const string&str2)const;//比较两个字符串是否相等
如:bool tag;
string str1=”string”,str2=”string1”,str3=”string”;
tag=(str1==str2);//tag=false
tag=(str1==str3);//tag=true
bool operator!=(const string&str1,const string&str2)const;//比较两个字符串是否不相等
如:bool tag;
string str1=”string”,str2=”string1”,str3=”string”;
tag=(str1!=str2);//tag=true
tag=(str1!=str3);//tag=false
bool operator>(const string&str1,const string&str2)const;//比较字符串str1是否大于字符串str2
如:bool tag;
string str0=”string0”,str1=”string1”,str2=”string2”;
tag=(str0>str1);//tag=false
tag=(str2>str1);//tag=true
bool operator>=(const string&str1,const string&str2)const;//比较字符串str1是否大于或等于字符串str2
如:bool tag;
string str0=”string”,str1=”string1”,str2=”string2”,str3=”string”;
tag=(str0>=str1);//tag=false
tag=(str2>=str1);//tag=true
tag=(str0>=str3);//tag=true
bool operator<(const string&str1,const string&str2)const;//比较字符串str1是否小于字符串str2
如:bool tag;
string str0=”string0”,str1=”string1”,str2=”string2”;
tag=(str0<str1);//tag=true
tag=(str2<str1);//tag=false
bool operator<=(const string&str1,const string&str2)const;//比较字符串str1是否小于或等于字符串str2
如:bool tag;
string str0=”string”,str1=”string1”,str2=”string2”,str3=”string”;
tag=(str0<=str1);//tag=true
tag=(str2<=str1);//tag=false
tag=(str0<=str3);//tag=true
int compare(const string&str)const;//比较当前字符串和str的大小。
如果当前字符串小于str,返回-1;如果相等,返回0;如果如果当前字符串小于str,返回-1的整数。
如:int tag;
string str=”string”,str1=”string1”,str2=”string1”,str3=”string3”;
tag=pare(str);//tag=-1
tag=pare(str2);//tag=0
tag=pare(str3);//tag=1
int compare(size_type p0,size_type n0,const string&str);//比较当前字符串从p 0开始的n0个字符组成的字符串与str的大小。
如果当前字符串小于str,返回-1;如果相等,返回0;如果当前字符串小于str,返回-1的整数。
如:int tag;
string str1="strstring",str2="string";
tag=pare(3,6,str2);//tag=0str1中的“string”与str2比较
tag=pare(1,6,str2);//tag=1str1中的”trstri”与str2比较
tag=pare(2,6,str2);//tag=-1str1中的”rstrin”与str2比较int compare(size_type p0,size_type n0,const string&str,size_type pos,size_t ype n);//比较当前字符串从p0开始的n0个字符组成的字符串与str中pos开始的n个字符组成的字符串的大小。
如果当前字符串小于str,返回-1;如果相等,返回0;如果当前字符串小于str,返回-1的整数。
如:int tag;
string str1="strstring",str2="string";
tag=pare(3,3,str2,0,3);//tag=0str1中的”str”与str2中的”str”比较
tag=pare(3,6,str2,0,3);//tag=1str1中的”string”与str2中的”str”1比较
tag=pare(2,3,str2,0,3);//tag=-1str1中的”rst”与str2中的”str”比较int compare(const char*s)const;//比较当前字符串和C-串s的大小。
如果当前字符串小于str,返回-1;如果相等,返回0;如果当前字符串小于str,返回-1的整数。
如:int tag;
string str=”string1”;
tag=pare(”string”);//tag=-1
tag=pare(”string1”);//tag=0
tag=pare(”string3”);//tag=1
int compare(size_type p0,size_type n0,const char*s);//比较当前字符串从p0开始的n0个字符组成的字符串与C-串s的大小。
如果当前字符串小于str,返回-1;如果相等,返回0;如果当前字符串小于str,返回-1的整数。
如:int tag;
string str="strstring";
tag=pare(3,6,"string");//tag=0str1中的“string”与str2比较
tag=pare(1,6,"string");//tag=1str1中的”trstri”与str2比较
tag=pare(2,6,"string");//tag=-1str1中的”rstrin”与str2比较int compare(size_type p0,size_type n0,const char*s,size_type pos,size_type n);//比较当前字符串从p0开始的n0个字符组成的字符串与C-串s中pos开始的n个字符组成的字符串的大小。
如果当前字符串小于str,返回-1;如果相等,返回0;如果当前字符串小于str,返回-1的整数。
如:int tag;
string str="strstring";
tag=pare(3,3,"string",0,3);//tag=0str1中的”str”与str2中的”str”比较
tag=pare(3,6,"string",0,3);//tag=1str1中的”string”与str2中的”str”1比较
tag=pare(2,3,"string",0,3);//tag=-1str1中的”rst”与str2中的”str”比较
八、string类的子串:
string substr(size_type pos=0,size_type n=npos)const;//返回pos开始的n个字符组成的字符串
如:string str1=”string”,str2;
str2=str1.substr(2,3);//str2=”rin”
九、string类的交换:
void swap(string&str);//交换当前字符串与str的值
如:string str1=”string1”,str2=”string2”;
str1.swap(str2);//str1=”string2”,str2=”string1”
如果刚开始定义了一个string,容量100,000个字符,接着逐步要erase()删除,到最后只需要10个字符。
这样的删除是减少了string的大小,但没有减少它的容量。
要避免你的string持有它不再需要的内存,你需要有一种方法来把它从曾经最大的容量减少到它现在需要的容量。
这样减少容量的方法常常被称为“收缩到合适(shrink to fit)”。
收缩到合适很容易实现,但代码……
这是你怎么修整你的竞争者string过剩容量的方法:
string(contestants).swap(contestants);
表达式string(contestants).swap(contestants)建立一个临时string,它是contestants的一份拷贝:string的拷贝构造函数做了这个工作。
但是,string的拷贝构造函数只分配拷贝的元素需要的内存,所以这个临时string没有多余的容量。
然后我们让临时string和contestants交换数据,这时我们完成了,contestants只有临时变量的修整过的容量,而这个临时变量则持有了曾经在contestants中的发胀的容量。
在这里(这个语句结尾),临时string被销毁,因此释放了以前contestants使用的内存。
【格式】:
string str;
...//使str变大,然后删除所有
string(str).swap(str);//在s上进行“收缩到合适”
【例子】:
string str;
for(int i=0;i<10;i++)
str+="string";
cout<<"收缩到合适之前:"<<endl;
cout<<"str="<<str<<endl<<"容量="<<str.capacity()<<endl;
str="string";
string(str).swap(str);
cout<<"收缩到合适之后:"<<endl;
cout<<"str="<<str<<endl<<"容量="<<str.capacity()<<endl;
【结果】:
收缩到合适之前:
str=stringstringstringstringstringstringstringstringstringstring
容量=63
收缩到合适之后:
str=string
容量=31
其实,这种方法并没有保证这个技术会真的消除多余的空间。
如果string想要的话,实现可以自由地给予它们过剩的空间,而且有时候它们想要。
比如,它们可能必须有一个最小容量限制,或者它们可能强制string的容量是2的整数次方。
(在在《Effective STL》作者的经历中,这样不规则的string实现比string实现更常见。
例子参见《Effective STL》条款15。
)这近似于“收缩到合适”,然而,并不是真的意味着“使容量尽可能小”,它意味着“使容量和这个实现可以尽量给容器的当前大小一样小”。
但是,只要没有切换不同的STL实现,这是你能做的最好的方法。
所以当你想对string进行“收缩到合适”时,就考虑“交换技巧”。
另外,交换技巧的变体可以用于清除容器和减少它的容量到你的实现提供的最小值。
你可以简单地和一个默认构造的临时string做个交换。
【格式】:
string str;
...//使用str
string().swap(str);//清除str而且最小化它的容量
【例子】:
string str;
for(int i=0;i<10;i++)
str+="string";
cout<<"清除容器之前:"<<endl;
cout<<"str="<<str<<endl<<"容量="<<str.capacity()<<endl;
string().swap(str);
cout<<"清除容器之后:"<<endl;
cout<<"str="<<str<<endl<<"容量="<<str.capacity()<<endl;
【结果】:
清除容器之前:
str=stringstringstringstringstringstringstringstringstringstring
容量=63
清除容器之后:
str=
容量=0
参考资料:《Effective STL》条款17:使用“交换技巧”来修整过剩容量
十、string类的查找函数:
size_type find(char c,size_type pos=0)const;//从当前字符串的pos开始查找字符c在当前字符串的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string:: npos。
如:int pos;
string str=”string”;
pos=str.find(‘i’);//等价于str.find(‘i’,0)pos=3
pos=str.find(‘i’,5);//pos=npos
size_type find(const char*s,size_type pos=0)const;//从当前字符串的pos开始查找C-串s在当前串中的位置。
默认位置是最后一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str=”string”;
pos=str.find("ing");//等价于str.find("ing",0)pos=3
pos=str.find("ing",5);//pos=npos
size_type find(const char*s,size_type pos,size_type n)const;//从当前字符串的pos开始查找C-串s中前n个字符在当前串中的位置。
默认位置是最后一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
pos=str.find("trinstr",1,3);//pos=1
pos=str.find("trinstr",2,3);//pos=npos
size_type find(const string&str,size_type pos=0)const;//从当前字符串的p os开始查找字符串s在当前串中的位置。
默认位置是最后一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str1=”string”,str2=”rin”;
pos=str1.find(str2);//等价于str.find(str2,0)pos=2
pos=str1.find(str2,5);//pos=npos
size_type rfind(char c,size_type pos=npos)const;//从当前字符串的pos开始从后向前查找字符c在当前串中的位置。
默认位置是最后一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
pos=str.rfind('i');//pos=3
pos=str.rfind('i',2);//pos=npos
size_type rfind(const char*s,size_type pos=npos)const;//从当前字符串的pos开始从后向前查找C-串s在当前串中的位置。
默认位置是最后一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str=”string”;
pos=str.rfind("ing");//pos=3
pos=str.rfind("ing",2);//pos=npos
size_type rfind(const char*s,size_type pos,size_type n)const;//从当前字符串的pos开始从后向前查找C-串s中前n个字符组成的字符串在当前串中的位置。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
pos=str.rfind("rinstr",4,3);//pos=2
pos=str.rfind("rinstr",1,3);//pos=npos
size_type rfind(const string&str,size_type pos=npos)const;//从当前字符串的pos开始从后向前查找字符串str在当前串中的位置。
默认位置是最后一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str1=”string”,str2=”rin”;
pos=str1.rfind(str2);//pos=2
pos=str1.rfind(str2,1);//pos=npos
size_type find_first_of(char c,size_type pos=0)const;//从当前字符串的po s开始查找字符c在当前字符串第一次出现的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
pos=str.find_first_of('r',);//pos=2
pos=str.find_first_of(‘r’,3);//pos=npos
size_type find_first_of(const char*s,size_type pos=0)const;//从当前字符串的pos开始查找当前串中第一个在C-串s的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
const char s[20]="ABCDitr1234";
pos=str.find_first_of(s,1);//pos=1
pos=str.find_first_of(s,2);//pos=2
pos=str.find_first_of(s,3);//pos=3
pos=str.find_first_of(s,4);//pos=npos
size_type find_first_of(const char*s,size_type pos,size_type n)const;//从当前字符串的pos开始查找当前串中第一个在C-串s的前n个字符的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
const char s[20]="ABCDitr1234";
pos=str.find_first_of(s,2,5);//pos=3
pos=str.find_first_of(s,4,5);//pos=npos
size_type find_first_of(const string&str,size_type pos=0)const;//从当前字符串的pos开始查找当前串中第一个在str的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str1="string",str2="ABCDitr1234";
pos=str1.find_first_of(str2,1);//pos=1
pos=str1.find_first_of(str2,2);//pos=2
pos=str1.find_first_of(str2,3);//pos=3
pos=str1.find_first_of(str2,4);//pos=npos
size_type find_first_not_of(char c,size_type pos=0)const;//从当前字符串的pos开始查找字符c不在当前字符串第一次出现的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
pos=str.find_first_not_of('t');//pos=0
pos=str.find_first_not_of('s');//pos=1
pos=str.find_first_not_of('s',3);//pos=3
size_type find_first_not_of(const char*s,size_type pos=0)const;//从当前字符串的pos开始查找当前串中第一个不在C-串s的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
const char s[20]="ABCDitr1234";
pos=str.find_first_not_of(s);//pos=0
pos=str.find_first_not_of(s,4);//pos=4
size_type find_first_not_of(const char*s,size_type pos,size_type n)const; //从当前字符串的pos开始查找当前串中第一个不在C-串s的前n个字符的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
const char s[20]="ABCDitr1234";
pos=str.find_first_not_of(s,1,4);//pos=1
pos=str.find_first_not_of(s,2,5);//pos=2
size_type find_first_not_of(const string&str,size_type pos=0)const;//从当前字符串的pos开始查找当前串中第一个在str的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str1="string",str2="ABCDitr1234";
pos=str1.find_first_not_of(str2);//pos=0
pos=str1.find_first_not_of(str2,3);//pos=4
size_type find_last_of(char c,size_type pos=spos)const;//从当前字符串的po s开始从后向前查找字符c在当前字符串第一次出现的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
pos=str.find_last_of('r');//pos=2
pos=str.find_last_of('r',3);//pos=2
pos=str.find_last_of('r',1);//pos=npos
size_type find_last_of(const char*s,size_type pos=spos)const;//从当前字符串的pos开始从后向前查找当前串中第一个在C-串s的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
const char s[20]="ABCDitr1234";
pos=str.find_last_of(s2);//pos=3
pos=str.find_last_of(s,5);//pos=3
pos=str.find_last_of(s,2);//pos=2
pos=str.find_last_of(s,0);//pos=npos
size_type find_last_of(const char*s,size_type pos,size_type n)const;//从当前字符串的pos开始从后向前查找当前串中第一个在C-串s的前n个字符的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
const char s[20]="ABCDitr1234";
pos=str.find_last_of(s,2,5);//pos=npos
pos=str.find_last_of(s,4,5);//pos=3
size_type find_last_of(const string&str,size_type pos=spos)const;//从当前字符串的pos开始从后向前查找当前串中第一个在str的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str1="string",str2="ABCDitr1234";
pos=str1.find_last_of(str2);//pos=3
pos=str1.find_last_of(str2,5);//pos=3
pos=str1.find_last_of(str2,2);//pos=2
pos=str1.find_last_of(str2,0);//pos=npos
size_type find_last_not_of(char c,size_type pos=0)const;//从当前字符串的pos开始从后向前查找字符c不在当前字符串第一次出现的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
pos=str.find_last_not_of('t');//pos=5
pos=str.find_last_not_of('g');//pos=4
pos=str.find_last_not_of('s',3);//pos=3
pos=str.find_last_not_of('i',3);//pos=2
size_type find_last_not_of(const char*s,size_type pos=0)const;//从当前字符串的pos开始从后向前查找当前串中第一个不在C-串s的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
const char s[20]="ABCDitr1234";
pos=str.find_first_not_of(s);//pos=0
pos=str.find_last_not_of(s,4);//pos=4
pos=str.find_last_not_of(s,3);//pos=0
size_type find_last_not_of(const char*s,size_type pos,size_type n)const; //从当前字符串的pos开始从后向前查找当前串中第一个不在C-串s的前n个字符的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str="string";
const char s[20]="ABCDitr1234";
pos=str.find_last_not_of(s,1,4);//pos=1
pos=str.find_last_not_of(s,4,5);//pos=4
size_type find_last_not_of(const string&str,size_type pos=0)const;//从当前字符串的pos开始从后向前查找当前串中第一个在str的位置。
默认位置是第一个元素。
成功返回其位置,失败返回string::npos。
如:int pos;
string str1="string",str2="ABCDitr1234";
pos=str1.find_last_not_of(str2);//pos=5
pos=str1.find_last_not_of(str2,3);//pos=0
小结:
find:查找
rfind:反向查找
find_first_of:从当前字符串一个一个查找,如果发现在目标串中,返回其位置。
find_first_not_of:从当前字符串一个一个查找,如果发现不在目标串中,返回其位置。
find_last_of:从当前字符串从后往前一个一个查找,如果发现在目标串中,返回其位置。
find_last_not_of:从当前字符串从后往前一个一个查找,如果发现不在目标串中,返回其位置。
例子:
#include<string>
#include<iostream>
using namespace std;
int main()
{
string strsrc="//*---String::find...()Test!......------";
string strdst="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz";
int first=strsrc.find_first_of(strdst);
int last=strsrc.find_last_of(strdst);
if(first==string::npos||last==string::npos)
{
cout<<"not find any characters"<<endl;
return-1;
}
cout<<strsrc.substr(first,last-first+1)<<endl;。