C++STL:string类的使用
Posted 山舟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++STL:string类的使用相关的知识,希望对你有一定的参考价值。
文章目录
前言
STL中的内容很多,所以文章中只介绍最常用、最好用的一部分。如果需要用到剩余的一些内容,可以到C++的官方网站上查找。
一、 string类
C语言中没有字符串这一类型,只能通过char数组来间接实现,字符串是以’\\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,而且底层空间需要用户自己管理,可能还会非法访问。
string是表示字符串的字符串类,该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作,包含在string头文件下(注意不是string.h)。
二、 string类的常用函数
1.构造函数
STL库中给出了下面7个构造函数,其中(1)、(2)和(4)最常用
使用如下:
int main()
{
string s1;
string s2("hello world");
string s3(s2);
return 0;
}
结果如下:
2.赋值运算符重载
代码如下:
int main()
{
std::string str1, str2, str3;
str1 = "hello world";
str2 = 'x';
str3 = str1;
cout << str1 << endl;
cout << str2 << endl;
cout << str3 << endl;
return 0;
}
结果如下:
3.三种遍历方式
(1)operator[]重载、下标
下面的代码中s.size()返回string中有效字符的个数(即不包含\\0)。
代码如下:
int main()
{
string s = "12345";
size_t i = 0;
for (i = 0; i < s.size(); i++)
cout << s[i] << " ";
cout << endl;
return 0;
}
结果如下:
(2)范围for
代码如下:
int main()
{
string s = "12345";
for (auto e : s)
cout << e << " ";
cout << endl;
return 0;
}
结果如下:
(3)迭代器
迭代器是各种STL容器遍历时通用的方法,对于string、vector这种简单的容器来说可能与其他遍历方法差不多,但到之后复杂的容器时用迭代器遍历是最方便的。
代码如下:
int main()
{
string s = "12345";
string::iterator it = s.begin();//前面加string告诉编译器找string类里的iterator
//而不是去找其他容器的iterator
while (it != s.end())//注意判断条件
{
cout << *it << " ";
it++;//it向后遍历
}
cout << endl;
return 0;
}
结果如下:
begin()返回第一个字符的迭代器、end()返回最后一个字符下一个位置的迭代器。
这里是第一次遇到迭代器,可以暂时将其理解为一个指针,但迭代器不一定全是指针,即下面的写法:
代码如下:
class string
{
public:
typedef char* iterator;
//...
private:
//...
}
还有反向迭代器可实现反向遍历,与上面正向迭代器同理。
代码如下:
int main()
{
string s = "12345";
string::reverse_iterator it = s.rbegin();//ebegin()返回最后一个字符的迭代器
while (it != s.rend())//rend()返回第一个字符前一个位置的迭代器。
{
cout << *it << " ";
it++;//注意这里是++而不是--
}
cout << endl;
return 0;
}
结果如下:
由上可知,迭代器遍历时区间是左闭右开的,即[begin(), end())、[rbegin(), rend()),begin()和rbegin()位置是可以被访问的,而end()和rend()位置不能被访问。
4.数据的插入与删除
(1)尾部插入数据
用push_back在字符串末尾插入单个字符,用append插入字符串。
代码如下:
int main()
{
string s;
s.push_back('h');
s.push_back('e');
s.push_back('l');
s.push_back('l');
s.push_back('o');
s.push_back(' ');
cout << s << endl;
s.append("world");
cout << s << endl;
string s1 = "!!!";
s.append(s1);
cout << s << endl;
return 0;
}
结果如下:
但实际情况中重载的operator+=是最方便的。
代码如下:
int main()
{
string s;
s += 'h';
s += 'e';
s += 'l';
s += 'l';
s += 'o';
s += ' ';
cout << s << endl;
s += "world";
cout << s << endl;
string s1 = "!!!";
s += s1;
cout << s << endl;
return 0;
}
结果如下:
注意:
(1)在string尾部追加字符时,push_back、append和+=三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串,而且写起来可读性很好。
(2)对string操作时,如果能够大概预估到要存储多少个字符,可以通过reserve提前把空间预留好。
(2)insert任意位置插入数据
注意是在给定的位置(下标)之后插入数据。
代码如下:
int main()
{
string s = "ad";
cout << s << endl;
s.insert(0, "bc");
cout << s << endl;
s.insert(4, "efg");
cout << s << endl;
s.insert(1000, "!!!");//一定要在合法的位置插入数据,否则会报错
cout << s << endl;
return 0;
}
结果如下:
(3)erase任意位置清除数据
注意是在给定的位置(下标)之后清除数据。
代码如下:
int main()
{
string s = "abcdefg";
s.erase(0, 1);//清除下标为0的位置后的1个数据
cout << s << endl;
s.erase(5, 10);//清除下标为5的位置后的10个数据,由于其后没有10个数据,所以全部清除结束
cout << s << endl;
s.erase(2);//清除下标为2的位置后的所有数据
cout << s << endl;
return 0;
}
结果如下:
5.resize与reserve
(1)resize
改变一个string对象的size,即对象中有效字符的个数。
代码如下:
int main()
{
string s1 = "abcd";
cout << "size:" << s1.size() << endl;
cout << "capacity:" << s1.capacity() << endl;
cout << s1 << endl << endl;
s1.resize(2);//size大于给定的值,则只保留给定的值的内容
cout << "size:" << s1.size() << endl;
cout << "capacity:" << s1.capacity() << endl;
cout << s1 << endl << endl;
s1.resize(5);//size小于给定的值,多余的部分默认给\\0
cout << "size:" << s1.size() << endl;
cout << "capacity:" << s1.capacity() << endl;
cout << s1 << endl << endl;
s1.resize(7, '!');//size小于给定的值,多余的部分也可给定,如这里给定为!
cout << "size:" << s1.size() << endl;
cout << "capacity:" << s1.capacity() << endl;
cout << s1 << endl << endl;
return 0;
}
结果如下:
注意上面结果中最后的字符串中间出现了三个空格,这里其实是s1.resize(5);时默认填充的三个\\0,但由于其是不可见字符,所以看起来是空格。
(2)reserve
即改变一个string对象的capacity,即对象中能存储有效字符的最大个数。
代码如下:
int main()
{
string s;
int prev = s.capacity();//获取当前string对象的capacity大小
for (char ch = 0; ch < 127; ch++)
{
s += ch;
//发生增容时打印capacity的变化
if (prev != s.capacity())
{
cout << "capacity:" << prev << "-->>" << s.capacity() << endl;
prev = s.capacity();
}
}
return 0;
}
结果如下:
6.c_str
返回C语言类型的字符串,即遇到\\0截止。
代码如下:
int main()
{
string s = "abcd";
s.resize(6);
s += "!!!";
cout << s.c_str() << endl;
cout << s << endl;
return 0;
}
结果如下:
resize时不够的两个位置默认用\\0补全,打印c_str遇到第一个\\0即停止,而直接打印s会打印[0,s.size())的全部内容。
7.查找
find函数用来查找一个string对象内有无某一字符或字符串并返回下标,找不到返回npos。
npos是string内的一个静态成员,类型为unsigned int,值为无符号整型的最大值。
代码如下:
int main()
{
string s = "hello world";
size_t pos = s.find(' ');
if (pos != string::npos)//判断是否找到
{
for (; pos < s.size(); pos++)
cout << s[pos];
cout << endl;
}
size_t pos1 = s.find('z');
if (pos1 == string::npos)
cout << "找不到" << endl;
return 0;
}
结果如下:
同理也有rfind函数,即倒着查找某一字符或字符串,此处不再赘述。
8.getline
cin相当于C语言中的scanf,遇到空格或换行停止读入;getline相当于C语言中的gets,遇到换行停止读入。
代码如下:
int main()
{
string s;
getline(cin, s);//注意写法
cout << s << endl << endl;
cin >> s;
cout << s << endl;
return 0;
}
结果如下:
感谢阅读,如有错误请批评指正
以上是关于C++STL:string类的使用的主要内容,如果未能解决你的问题,请参考以下文章