下面介绍一些string类常用的方法,文章内容过长,如有错误烦请指正,谢谢.
目录
1.在string对象后面进行拼接---operator+= append() push_back()
1.把string对象转换为c语言字符串的样式---c_str()
2.比较两个字符串---compare() 重载的>,==,<,>=,<=,!=
一.构造,拷贝构造,赋值重载
1.构造函数与拷贝构造函数
//构造函数
string();//无参构造函数
//使用例子:
string s1;
string (const char* s);//c语言字符串构造
//使用例子:
string s2("abc");//写法一
string s2="abc"; //写法二
template <class InputIterator>
string (InputIterator first, InputIterator last);//迭代器
//使用例子:
string s3(s2.begin(), s2.end());
//拷贝构造函数
string (const string& str);
//使用例子:
string s4(s3);//写法一
string s4=s3;//写法二
2.赋值重载函数
string& operator= (const string& str);//string对象
//使用例子: s4=s2;
string& operator= (const char* s);//C语言字符串
//使用例子: s4="abcd";
string& operator= (char c);//字符
//使用例子: s4='e';
二.迭代器
1.正向迭代器---begin() end()
//返回一个正向迭代器,指向第一个元素
iterator begin();
const_iterator begin() const;
//返回一个正向迭代器,指向最后一个元素的下一个位置
iterator end();
const_iterator end() const;
//使用例子:
string s1("abcdefg");
for (string::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << " ";
}
//运行结果:a b c d e f g
2.反向迭代器---rbegin() rend()
//返回一个反向迭代器,指向最后一个元素
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
//返回一个反向迭代器,指向第一个元素的上一个位置
reverse_iterator rend();
const_reverse_iterator rend() const;
//使用例子:
string s1("abcdefg");
for (string::reverse_iterator it = s1.rbegin(); it != s1.rend(); it++)
{
cout << *it << " ";
}
//运行结果:g f e d c b a
3.正向常量迭代器---cbegin() cend()
//返回一个正向常量迭代器,指向第一个元素
const_iterator cbegin() const noexcept;
//返回一个正向常量迭代器,指向最后一个元素的下一个位置
const_iterator cend() const noexcept;
//使用例子:
const string s1("abcdefg");
for (string::const_iterator it = s1.cbegin(); it != s1.cend(); it++)
{
cout << *it << " ";
}
//运行结果:a b c d e f g
4.反向常量迭代器---crbegin() crend()
//返回一个反向常量迭代器,指向最后一个元素
const_reverse_iterator crbegin() const noexcept;
//返回一个反向常量迭代器,指向第一个元素的上一个位置
const_reverse_iterator crend() const noexcept;
//使用例子:
const string s1("abcdefg");
for (string::const_reverse_iterator it = s1.crbegin(); it != s1.crend(); it++)
{
cout << *it << " ";
}
//运行结果:g f e d c b a
三.与size和capacity有关的方法
1.获取有效字符的个数---size() length()
//方法:
size_t size() const;
size_t length() const;
//使用例子:
string s1("abcdefg");
cout << s1.size() << endl;//结果为7
cout << s1.length() << endl;//结果为7
2.获取容量的大小---capacity()
//方法:
size_t capacity() const;
//使用例子:
string s1("abcdefg");
cout << s1.capacity() << endl;//不同的编译器结果可能会不同(在vs2022下,结果为15)
3.扩容方法---reserve()
//方法:
void reserve (size_t n = 0);
//使用方法:
string s1("abcdefghijklmnopqrstuvwxyz");
cout << s1.capacity() << endl;//不同编译器结果可能不同(vs2022结果为31)
s1.reserve(100);
cout << s1.capacity() << endl;//不同编译器结果可能不同(vs2022结果为111)
s1.reserve(31);
cout << s1.capacity() << endl;//vs2022结果为111
当n>当前的capacity时,会把容量扩容到n
当n<=当前的capacity时,则不会对当前的capacity做处理(即capacity不变)(可能一些编译器会对长度较短的字符串有优化机制,这里不做讨论)
4.重新设置有效字符的个数---resize()
//方法:
void resize (size_t n);
void resize (size_t n, char c);
//使用例子:
string s1("hello world");
s1.resize(15,'A');
cout << s1 << " " << s1.size() << endl;//结果为hello worldAAAA 15
s1.resize(20);
cout << s1 << " " << s1.size() << endl;//结果为hello worldAAAA 20
s1.resize(11);
cout << s1 << " " << s1.size() << endl;//结果为hello world 11
s1.resize(5);
cout << s1 << " " << s1.size() << endl;//结果为hello 5
s1.resize(2, 'Z');
cout << s1 << " " << s1.size() << endl;//结果为he 2
这两个重载函数都是将字符串中有效字符个数改变到n个.
使用void resize (size_t n)或void resize (size_t n, char c)时,
如果n大于当前的size,那么将新增的部分置成'\0'(或者是c),并且有可能会改变capacity(发生了扩容)
如果n小于等于当前的size,那么会直接截断,保留前n个有效字符,不会改变capacity
5.清空有效字符---clear()
//方法:
void clear();
//使用例子:
string s1("hello world");
cout << s1 << " " << s1.size() <<" "<<s1.capacity()<<endl;//hello world 11 15
s1.clear();
cout << s1 << " " << s1.size() <<" "<<s1.capacity()<<endl;// 0 15
clear()会清除所有的有效字符,但是不会改变capacity
6.判断字符串是否为空串---empty()
//方法:
bool empty() const;
//使用例子:
string s1("hello world");
cout << s1.empty() << endl;//结果为0
string s2;
cout << s2.empty() << endl;//结果为1
当字符串为空串时,返回true,否则返回false
四.元素访问
1.通过[]访问---operator[]
//方法:
char& operator[] (size_t pos);//可读可写
const char& operator[] (size_t pos) const;//只读
//使用方法:
const string s1("hello world");
cout << s1[0] << " " << s1[10] << endl;//结果为h d
这种访问方式与普通数组相同,越界访问时不会像at方法抛异常
2.at()方法
//方法:
char& at (size_t pos);
const char& at (size_t pos) const;
//使用例子:
const string s1("hello world");
cout << s1.at(0) << " " << s1.at(10) << endl;//结果为h d
//cout << s1.at(100) << endl;这里会抛异常
当出现越界访问的情况时,会抛异常,安全性比operator[]高
五.修改操作
1.在string对象后面进行拼接---operator+= append() push_back()
1.1.operator+=
//方法:
string& operator+= (char c); //后接字符
string& operator+= (const char* s); //后接c语言字符串
string& operator+= (const string& str);//后接string对象
//使用例子:
string s1("h");
s1 += 'e';
cout << s1 << endl;//结果为he
s1 += "llo";
cout << s1 << endl;//结果为hello
string s2(" world");
s1 += s2;
cout << s1 << endl;//结果为hello world
1.2.append()
//方法:
string& append (size_t n, char c); //后接n个c
string& append (const char* s); //后接c语言字符串
string& append (const string& str);//后接string对象
template <class InputIterator>
string& append (InputIterator first, InputIterator last);//通过迭代器来后接
//使用例子:
string s1("h");
s1.append(1,'e');
cout << s1 << endl;//结果为he
s1.append("llo");
cout << s1 << endl;//结果为hello
string s2(" wo");
s1.append(s2);
cout << s1 << endl;//结果为hello wo
string s3("rld");
s1.append(s3.begin(), s3.end());
cout << s1 << endl;//结果为hello world
1.3.push_back()
//方法:
void push_back (char c);//后接一个字符
//使用例子:
string s1("hello worl");
s1.push_back('d');
cout << s1;//结果为hello world
2.与=作用相同---assign()
//方法:
string& assign (size_t n, char c); //n个字符c
string& assign (const char* s); //c语言字符串
string& assign (const string& str); //string对象
template <class InputIterator>
string& assign (InputIterator first, InputIterator last);//迭代器
//使用例子:
string s1;
s1.assign(10,'a');
cout << s1 << endl;//结果为aaaaaaaaaa
s1.assign("blue archive");
cout << s1 << endl;//结果为blue archive
string s2("nixiankaide");
s1.assign(s2);
cout << s1 << endl;//结果为nixiankaide
string s3("yuanshen qidong");
s1.assign(s3.begin(), s3.end());
cout << s1 << endl;//结果为yuanshen qidong
3.在任意位置插入---insert()
//方法:
//在pos位置插入n个字符c
string& insert (size_t pos, size_t n, char c);
//在pos位置插入C语言字符串
string& insert (size_t pos, const char* s);
//在pos位置插入一个string对象
string& insert (size_t pos, const string& str);
//在p位置(迭代器)通过迭代器插入
template <class InputIterator>
void insert (iterator p, InputIterator first, InputIterator last);
//使用例子:
string s1("beng_hua_dao");
s1.insert(8,1,'i');
cout << s1 << endl;//beng_huai_dao
s1.insert(9, "_");//也可以通过这种方式以字符串形式插入字符
cout << s1 << endl;//beng_huai__dao
s1.insert(10,"xing_qiong");
cout << s1 << endl;//beng_huai_xing_qiong_dao
string s2("_t");
s1.insert(20,s2);
cout << s1 << endl;//beng_huai_xing_qiong_t_dao
string s3("ie");
s1.insert(s1.begin()+22, s3.begin(), s3.end());//这里的pos位置是用迭代器表示的
cout << s1 << endl;//beng_huai_xing_qiong_tie_dao
注意:pos是从0开始,取值范围为[0,s.size()],如果pos不在此范围内,程序会运行失败.
4.在任意位置删除---erase()
//方法:
//删除从pos位置开始,长度为len的区间(最常用)
string& erase (size_t pos = 0, size_t len = npos);
//通过迭代器删除一个字符
iterator erase (iterator p);
//通过迭代器删除一段区间
iterator erase (iterator first, iterator last);
//使用例子:
string str("This is an example sentence.");
cout << str << endl;// "This is an example sentence."
str.erase(10, 8);
cout << str << endl;// "This is an sentence."
str.erase(str.begin() + 9);
cout << str << endl;// "This is a sentence."
str.erase(str.begin() + 5, str.end() - 9);
cout << str << endl;// "This sentence."
注意:pos是从0开始,取值范围为[0,s.size()],如果pos不在此范围内,程序会运行失败.
方法一的len的缺省值是npos,npos的值是size_t所能表示的最大值(18,446,744,073,709,551,615,不过一般写成-1).如果len==npos || pos+len>=s.size(),那么就是从pos位置开始全部删掉,pos的缺省值为0.
//举例说明:
string s1("hello world");
s1.erase(9,10);
cout << s1 << endl;//结果为hello wor
s1.erase(6);
cout << s1 << endl;//结果为hello
s1.erase();
cout << s1 << endl;//结果为
5.删除最后一个字符---pop_back()
//方法:
void pop_back();
//使用例子:
string s1("CS qi_dong!");
cout << s1 << endl;//CS qi_dong!
s1.pop_back();
cout << s1 << endl;//CS qi_dong
6.对一部分区间进行替换---replace()
//方法1:pos-len版
//将从pos位置,长度为len的区间替换成string对象
string& replace (size_t pos, size_t len, const string& str);
//将从pos位置,长度为len的区间替换成c语言字符串
string& replace (size_t pos, size_t len, const char* s);
//将从pos位置,长度为len的区间替换成n个字符c
string& replace (size_t pos, size_t len, size_t n, char c);
//方法2:迭代器版
//把[i1,i2)区间替换成string对象
string& replace (iterator i1, iterator i2, const string& str);
//把[i1,i2)区间替换成c语言字符串
string& replace (iterator i1, iterator i2, const char* s);
//把[i1,i2)区间替换成n个字符c
string& replace (iterator i1, iterator i2, size_t n, char c);
//使用例子1:pos-len版
string s1("yuan_shen_qi_dong");
string s2("beng_huai_san");
s1.replace(0,9,s2);
cout << s1 << endl;//beng_huai_san_qi_dong
s1.replace(0,13,"blue_archive");
cout << s1 << endl;//blue_archive_qi_dong
s1.replace(0, 5, 1, 'C');
s1.replace(1, 7, 1, 'S');
cout << s1 << endl;//CS_qi_dong
//使用例子2:迭代器版
string s1("yuan_shen_qi_dong");
string s2("beng_huai_san");
s1.replace(s1.begin(), s1.begin()+9, s2);
cout << s1 << endl;//beng_huai_san_qi_dong
s1.replace(s1.begin(), s1.begin()+ 13, "blue_archive");
cout << s1 << endl;//blue_archive_qi_dong
s1.replace(s1.begin(), s1.begin()+5, 1, 'C');
s1.replace(s1.begin()+1, s1.begin()+8, 1, 'S');
cout << s1 << endl;//CS_qi_dong
注意:
1.pos-len版
①.pos是从0开始,取值范围为[0,s.size()],如果pos不在此范围内,程序会运行失败.
②.当pos+len>=s.size()时,则从pos位置开始全部进行替换
2.迭代器版
①.迭代器i1要<=迭代器i2并且不能越界,否则程序运行失败
六.截取,查找操作
1.从string对象内截取一段内容---substr()
//方法:
//从pos位置开始,截取长度为len的区间
string substr (size_t pos = 0, size_t len = npos) const;
//使用例子:
string s1("yuan_shen_qi_dong");
string s2 = s1.substr();
cout << s2 << endl;//yuan_shen_qi_dong
string s3 = s1.substr(10);
cout << s3 << endl;//qi_dong
string s4 = s1.substr(5,4);
cout << s4 << endl;//shen
注意:
①.len的缺省值是npos,如果len==npos || pos+len>=s.size(),那么就是从pos位置开始全部截取.
②.pos的缺省值是0,取值范围为[0,s.size()],如果pos不在此范围内,程序会运行失败.
2.find系列
2.1.从pos位置开始正向找---find()
//方法:
//从pos位置开始正向找string对象str第一次出现的位置,找到了返回下标,没找到返回npos
size_t find (const string& str, size_t pos = 0) const;
//从pos位置开始正向找c语言字符串第一次出现的位置,找到了返回下标,没找到返回npos
size_t find (const char* s, size_t pos = 0) const;
//从pos位置开始反向找字符c第一次出现的位置,找到了返回下标,没找到返回npos
size_t find (char c, size_t pos = 0) const;
//使用例子:
string s1("yuan_shen_qi_dong");
string s2("yuan_shen");
cout << s1.find(s2) << endl;//0
cout << s1.find(s2, 1) << endl;//18446744073709551615(npos)
cout << s1.find("an") << endl;//2
cout << s1.find('n',4) << endl;//8
注意:
①.pos的缺省值为0;即使pos>=s.size(),也不会报错,而是返回npos
2.2.从pos位置开始反向找---rfind()
//方法:
//从pos位置开始反向找string对象str第一次出现的位置,找到了返回下标,没找到返回npos
size_t rfind (const string& str, size_t pos = npos) const;
//从pos位置开始反向找c语言字符串第一次出现的位置,找到了返回下标,没找到返回npos
size_t rfind (const char* s, size_t pos = npos) const;
//从pos位置开始反向找字符c第一次出现的位置,找到了返回下标,没找到返回npos
size_t rfind (char c, size_t pos = npos) const;
//使用例子:
string s1("yuan_shen_qi_dong");
string s3("qi_dong");
cout << s1.rfind(s3) << endl;//10
cout << s1.rfind(s3, 1) << endl;//18446744073709551615(npos)
cout << s1.rfind("an") << endl;//2
cout << s1.rfind('n', 4) << endl;//3
注意:
①.pos的缺省值为npos
2.3.find_first_of()
作用:从pos位置(pos默认为0)开始正向找是某一字符或者某一字符串中的任意一个字符的第一次出现的位置,找到返回下标,没找到返回npos
//方法:
//针对string对象
size_t find_first_of (const string& str, size_t pos = 0) const;
//针对c语言字符串
size_t find_first_of (const char* s, size_t pos = 0) const;
//针对字符
size_t find_first_of (char c, size_t pos = 0) const;
//使用例子:
string s1("yuan_shen_qi_dong");
string s2("abcd");
cout << s1.find_first_of(s2) << endl;//2
//解释:从0位置开始正向找,因为s1[2]='a',然后'a'又在s2内存在
cout << s1.find_first_of(s2,3) << endl;//13
//解释:从3位置开始正向找,因为s1[13]='d',然后'd'又在s2内存在
cout << s1.find_first_of("cs") << endl;//5
//解释:从0位置开始正向找,因为s1[5]='s',然后"cs"内有字符's'
cout << s1.find_first_of('v') << endl;//18446744073709551615(npos)
//解释:从0位置开始正向找,因为'v'不存在于s1
2.4.find_last_of()
作用:从pos位置(pos默认为npos)开始反向找是某一字符或者某一字符串中的任意一个字符的第一次出现的位置,找到返回下标,没找到返回npos
//方法:
//针对string对象
size_t find_last_of (const string& str, size_t pos = npos) const;
//针对c语言字符串
size_t find_last_of (const char* s, size_t pos = npos) const;
//针对字符
size_t find_last_of (char c, size_t pos = npos) const;
//使用例子:
string s1("yuan_shen_qi_dong");
string s2("abcd");
cout << s1.find_last_of(s2) << endl;//13
//解释:从默认位置开始反向找,因为s1[13]='d',然后'd'又在s2内存在
cout << s1.find_last_of(s2,3) << endl;//2
//解释:从3位置开始反向找,因为s1[2]='a',然后'a'又在s2内存在
cout << s1.find_last_of("cs") << endl;//5
//解释:从默认位置开始反向找,因为s1[5]='s',然后"cs"内有字符's'
cout << s1.find_last_of('v') << endl;//18446744073709551615(npos)
//解释:从默认位置开始反向找,因为'v'不存在于s1
2.5.find_first_not_of()
作用:从pos位置(pos默认为0)开始正向找不是某一字符或不是某一字符串中的任意一个字符的第一次出现的位置,找到返回下标,没找到返回npos
//方法:
//针对string对象
size_t find_first_not_of (const string& str, size_t pos = 0) const;
//针对c语言字符串
size_t find_first_not_of (const char* s, size_t pos = 0) const;
//针对字符
size_t find_first_not_of (char c, size_t pos = 0) const;
//使用例子:
string s1("yuan_shen_qi_dong");
string s2("yyds");
string s3(s1);
cout << s1.find_first_not_of(s2) << endl;//1
//解释:从0位置开始正向找,因为s1[1]='u',然后'u'不存在于s2
cout << s1.find_first_not_of(s2,3) << endl;//3
//解释:从3位置开始正向找,因为s1[3]='n',然后'n'不存在于s2
cout << s1.find_first_not_of("yuanshen") << endl;//4
//解释:从0位置开始正向找,因为s1[4]='_',然后'_'不存在于字符串"yuanshen"
cout << s1.find_first_not_of('v') << endl;//0
//解释:从0位置开始正向找,因为s1[0]='y',然后'y'!='v'
cout << s1.find_first_not_of(s3) << endl;//18446744073709551615(npos)
//解释:从0位置开始正向找,因为s1的每个字符都在s3里面,所以找不到,返回npos
2.6.find_last_not_of()
作用:从pos位置(pos默认为npos)开始反向找不是某一字符或不是某一字符串中的任意一个字符的第一次出现的位置,找到返回下标,没找到返回npos
//方法:
//针对string对象
size_t find_last_not_of (const string& str, size_t pos = npos) const;
//针对c语言字符串
size_t find_last_not_of (const char* s, size_t pos = npos) const;
//针对字符
size_t find_last_not_of (char c, size_t pos = npos) const;
//使用例子:
string s1("yuan_shen_qi_dong");
string s2("ggbnb");
string s3(s1);
cout << s1.find_last_not_of(s2) << endl;//14
//解释:从默认位置开始反向找,因为s1[14]='o',然后'o'不存在于s2
cout << s1.find_last_not_of(s2,3) << endl;//2
//解释:从3位置开始反向找,因为s1[2]='a',然后'a'不存在于s2
cout << s1.find_last_not_of("qidong") << endl;//12
//解释:从默认位置开始反向找,因为s1[12]='_',然后'_'不存在于字符串"qidong"
cout << s1.find_last_not_of('v') << endl;//16
//解释:从默认位置开始反向找,因为s1[16]='g',然后'g'!='v'
cout << s1.find_last_not_of(s3) << endl;//18446744073709551615(npos)
//解释:从默认位置开始反向找,因为s1的每个字符都在s3里面,所以找不到,返回npos
七.其他
1.把string对象转换为c语言字符串的样式---c_str()
//方法:
//返回一个const char*指针(只能读不能写)
const char* c_str() const;
使用例子:
string s1("hehe");
const char* p1 = s1.c_str();
cout << p1 << " " <<s1.capacity()<<endl;//hehe 15(vs2022环境)
cout << (void*)p1 << endl;//000000048254F770(这是地址)
s1.replace(0,s1.size(),20,'c');//这里会发生异地扩容
p1 = s1.c_str();//如果没有这句,会发生非法访问
cout << p1 << " "<<s1.capacity()<<endl;//cccccccccccccccccccc 31(vs2022环境)
cout << (void*)p1 << endl;//0000017A86020C30(这是地址)
从上面的例子可以看出当string对象发生异地扩容时,原先的地址已经不能使用(因为已经被释放了),需要重新用c_str()返回新的地址才能继续使用.
2.比较两个字符串---compare() 重载的>,==,<,>=,<=,!=
比较原理:比较同下标元素的ASCII值(或字典序),按照下标从小到大依次比较(比较的不是字符串的长度);
返回值:小于返回<0的数,等于返回0,大于返回>0的数
//方法:
//针对string对象
int compare (const string& str) const;
//针对c语言字符串
int compare (const char* s) const;
//使用例子:
string s1("abcd");
string s2("hh");
string s3("aaa");
cout << s1.compare(s2) << endl;//-1
cout << s1.compare(s3) << endl;//1
cout << s1.compare("abcd") << endl;//0
也可以通过重载的>,==,<,>=,<=,!=进行比较(这六个运算符重载均为全局函数),返回值为true 或 false
//使用例子:
string s1("abcd");
string s2("hh");
string s3("aaa");
cout << (s1>s2) << endl;//false
cout << (s1>s3) << endl;//true
cout << ("abcd"==s1) << endl;//true
3.swap()
//swap分为两种:
//一种是成员函数:
void swap (string& str);
//一种是全局函数:
void swap (string& x, string& y);
string类的swap函数是通过交换两个string对象的成员变量来实现的
//以下代码只是为了展示原理,实际实现方式可能有所不同
void swap(string& s1)
{
std::swap(_str, s1._str);//_str为一个char* 指针,存储字符串
std::swap(_size, s1._size);//_size为一个size_t变量,存储有效字符的个数
std::swap(_capacity, s1._capacity);//_capacity为一个size_t变量,存储容量大小
}
4.operator+()(全局函数)
//函数:
//string对象+string对象
string operator+ (const string& lhs, const string& rhs);
//c语言字符串+string对象
string operator+ (const string& lhs, const char* rhs);
string operator+ (const char* lhs, const string& rhs);
//字符+string对象
string operator+ (const string& lhs, char rhs);
string operator+ (char lhs, const string& rhs);
//使用例子:
string s1("hello ");
string s2("world");
cout << s1 + s2 << endl;//hello world
cout << "abcd " + s1 << endl;//abcd hello
cout << 'a' + s1 << endl;//ahello
5.getline()(全局函数)
作用:通过getline()可以读取一行或者多行
//函数:
//不指定分隔符(遇到'\n'结束,只能读取一行)
istream& getline (istream& is, string& str);
//指定分隔符(遇到分隔符delim结束,可以读多行)
istream& getline (istream& is, string& str, char delim);
//使用例子:
string s1;
getline(cin,s1);
//输入:ab cd efg
cout << s1;
//输出:ab cd efg
string s1;
getline(cin,s1,'!');
//输入:ab cd efg
// hi jk lmn
// op!
cout << s1;
//输出:ab cd efg
// hi jk lmn
// op