C++之STL——string类

概念

string类是C++中表示字符串的结构,可以将其认为是C语言的字符串与其相关的函数封装在一起实现的类。避免了用户自己管理底层空间以及越界访问。

string类的常用接口

1、string类对象的常见构造类型

在这里插入图片描述

int main()
{
	string s1;
	string s2("hello world!");
	string s3(10, 'x');
	string s4(s2);
	return 0;
}

在这里插入图片描述

2、string类对象的容量操作

(1) size()函数
在这里插入图片描述

size()函数是用于返回字符串有效字符长度。
在这里插入图片描述
(2) capacity()函数
在这里插入图片描述

capacity()函数用于返回对象的空间总大小。
在这里插入图片描述
可以看到,s1的字符总数为12个,而容量为15个,说明在开辟空间的时候编译器默认给对象的容量是15个。
(3) empty()函数
在这里插入图片描述

empty()函数用于检测字符串是否为空,是返回true,非空返回false。
在这里插入图片描述
(4) clear()函数
在这里插入图片描述

clear()函数用于清空有效字符。
在这里插入图片描述
可以看到,在使用clear()函数,s1变为空字符串。
(5) reserve()函数
在这里插入图片描述

reverse()函数用于为字符串预留n个空间,可以看作是在对象中增加n个空间,减少后续的开销。这里分为两种情况:
a. 预留的空间大于可用空间
在这里插入图片描述
s1本身的容量为15个,在用reserve函数增加100个之后,变成了111个。这里没有变成115个是因为,s1对象本身只用可11个有效空间,reserve函数将没有用到的空间也当作预留的空间。
b. 预留的空间小于可用空间
在这里插入图片描述
这里s1对象本身用了11个空间,此时我们用reserve函数将其改为5个,可以看到这样是不行的,当改变的空间大小小于底层的空间总大小时,reserve函数不会改变容量大小。
(6) resize()函数
在这里插入图片描述

resize()函数用于将有效字符的个数改为n个,如果n大于有效字符的个数,没有给定字符默认用’\0’填充,如果给定字符就用指定字符填充。

int main()
{
	string s1("hello world!");
	s1.resize(20);
	string s2("hello world!");
	s1.resize(20, 'a');
	return 0;
}

在这里插入图片描述
s1调用resize()函数没有指定字符,编译器默认用’\0’代替。
在这里插入图片描述
s2调用resize()函数时指定字符’a’,编译器将多出的空间用’a’填充。

4、string类对象的访问及遍历操作

(1) operator[]
在string类中,对[]进行了重载,本身string类实例化之后对应的是一个对象,但是将[]重载之后,就可以通过"[]"像数组一样来访问对象的内容以及对内容进行修改,也就是返回pos位置的字符和修改pos位置的字符。
在这里插入图片描述
由上图可以看出,通过[]操作符可以实现对对象内容的访问和更改。
(2) begin + end
通过begin()可以获得第一个字符的迭代器,end()可以获得最后一个字符的下一个位置的迭代器(迭代器的具体内容会在后面讲解),通过begin()和end()就可以实现对一个string对象的遍历。
在这里插入图片描述
(3) rbegin 和 rend
细心的同学可以发现,rbegin和rend只是在begin和end前面多加了一个r,也就是说,rbegin和rend是获取逆向的迭代器。rbegin()是获取最后一个字符的迭代器,rend()是获得第一个字符的前一个位置的迭代器。
在这里插入图片描述
上图就是逆向迭代器的用法。
(4)三种遍历方式
通过上面三种类对象的访问方式的学习,我们在这里可以列举出三种对于类对象的遍历方式:
第一种: for + operator[]

for(int i = 0; i < (int)s.size(); ++i)
	cout << s[i] << endl;

第二种:迭代器

string::iterator it = s.begin();
while(it != s.end())
{
	cout << *it << endl;
	++it;
{


string::reverse_iterator rit = s.rbegin();
while(rit != s.rend())
	cout << *rit << endl;

第三种:范围for
这个是我们在前面讲过的auto关键字。

string s("Hello World!");
for(auto c : s)
	cout << c << endl;

3、string类对象的修改操作

(1) push_back()函数
在这里插入图片描述

push_back()函数的作用是在字符串后面尾插字符c。

int main()
{
	string s1("Hello World!");
	cout << s1 << endl;
	s1.push_back('b');
	cout << s1 << endl;
	return 0;
}

上面代码中,s1被初始化为"Hello World!"字符串,然后通过push_back()函数在s1后面尾插一个字符b。
在这里插入图片描述
注意:push_back()函数的参数不能是字符串,只能是字符。
(2) 重载+=运算符
在这里插入图片描述
如果想要在类对象的后面继续连接字符串,就需要用到重载的+=运算符。作用是在字符串后面追加字符串str。

int main()
{
	string s1("Hello World!");
	cout << s1 << endl;
	s1 += "abc";
	cout << s1 << endl;
	return 0;
}

在这里插入图片描述
可以看出初始化为"Hello World!“的s1对象用”+=“连接了"abc”,可以完成字符串的追加操作。
(4) c_str()函数
c_str函数的作用是返回C格式的字符串,也就是返回char类型的字符串。
虽然string类为了和C格式的字符串尽量相似,在字符串的末尾也加上了’ \0 ',但是与C格式的类型还是不同的,因此,这个接口专门用来返回char
格式的字符串。

int main()
{
	string s1("hello world!");
	cout << "s1的类型为:" << typeid(s1).name() << endl;
	cout << "s1.c_str()返回的类型为" << typeid(s1.c_str()).name() << endl;
	return 0;
}

在上面的代码中,我们定义了一个string类型的对象s1,通过c_str()函数得到它的C格式的字符串,通过typeid运算符(typeid运算符用来获取一个表达式的类型信息),可以看出,s1是string类的,而c_str()函数返回的则是char const 类型的。
在这里插入图片描述
(5) find()函数
find()函数的声明如下:
在这里插入图片描述
find()函数通常有两个参数,一个是要查找的字符或者字符串,字符的类型是char,字符串的类型是char
或者string;另一个是要查找的位置,查找的位置可以自己给出,如果没有给出的话,有一个默认的缺省值0。

find()函数的返回值是要查找的内容第一次出现的位置,如果没有找到对应的内容,则会返回npos(npos是string类定义的一个静态变量,值为-1,但由于npos是无符号整型的类型,因此没有找到的返回值为无符号整型的最大值)。

	string s1("hello world! good morning!");
	size_t pos = s1.find("hello");//不给pos参数,默认为0
	cout << pos << endl;
	pos = s1.find("hello", 3);
	cout << pos << endl;

分别从第0个位置和第3个位置找字符串"hello",得到的结果,一个返回的是"hello"第1次出现的位置下标0,另一个则返回的是无符号整型的最大值4294967295。
在这里插入图片描述
(6)rfind()函数
rfind()函数与find函数的功能是相似的,不同的是rfind()函数是从字符串的末尾开始找,返回第一次找到的位置。

5、string类的非成员函数

(1)重载>>运算符和重载<<运算符
对于一个string类的对象,如果用标准库中的<<和>>运算符是没有办法直接将string类对象的内容打印出来的。
在这里插入图片描述
在这里插入图片描述

如上面两张图所示,标准库中的<<和>>运算符只重载了比较基本的数据类型,并没有将string类的输入和输出进行重载,因此我们想要直接打印string类对象的内容,就需要在string类中重载<<和>>运算符。
(2) getline函数
假如想在string类的对象中输入一串字符串,我们用标准输入来试一下:

	string s1;
	cin >> s1;
	cout << s1 << endl;

然而得到的结果是这样的:
在这里插入图片描述
想要对string类对象输入hello world,结果只输入进去hello,这不是我们想要的结果。
出现这种情况是因为,cin在输入字符串的时候,识别出空格或者换行就会默认为输入结束,不管后面还有多少的东西。

对于这种情况,就要用getline()函数来进行输入。
getline()函数是非成员函数,因此调用时直接调用即可,其声明如下:
在这里插入图片描述
第一个参数是标准输入流,用来进行输入操作;第二个参数是要输入的string对象。
用法如下:

	string s1;
	getline(cin, s1);
	cout << s1 << endl;

这次输入保留了输入过程中的空格,可以读取一整行数据。
但是注意:geiline()函数遇到换行符就读取结束,也就是说getline读取的也只能是一行数据

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值