ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【C++ STL学习之路】---------string

2021-03-30 17:04:48  阅读:159  来源: 互联网

标签:字符 函数 STL basic 字符串 size --------- string


目录

string是什么?

C语言中的字符串

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,
但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

标准库中的string类

2.1 string类

string类的文档介绍

  1. 字符串是表示字符序列的类
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

总结:

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;
  4. 不能操作多字节或者变长字符的序列。

在使用string类时,必须包含#include头文件以及using namespace std;

为什么要定义string?

前面简述了,C语言中的字符串的缺点,这里总结一下,

  1. 容易越界访问
  2. 字符串指针和字符串数组有所区别
  3. 字符0和‘\0’混用导致截断字符串

因为这些缺点,C++中定义了string类,解决了上面的问题,还定义了一系列的接口函数,方便人使用。

string怎么用?

string的进阶用法大家可以参考CPP官网给出的文档
链接: CPP官网string文档.

下面只介绍一些基本用法和相关知识点

constructor系列函数

在这里插入图片描述

常用:

 void Teststring()
{
string s1; // 构造空的string类对象s1
string s2("hello bit"); // 用C格式字符串构造string类对象s2
string s3(s2); // 拷贝构造s3
}

上面介绍了几个默认成员函数,析构和“=”运算符重载没有介绍。

  1. 析构自动在类的生命周期结束时,自动调用。
  2. “=”运算符重载涉及深浅拷贝,参考下面这篇文章。

链接: 深浅拷贝.

迭代器

官方给出了8种迭代器,按,从前到后,从后到前,以及是否可修改划分。
在这里插入图片描述
在string类里,迭代器底层其实就是字符指针,
begin指向第一个字符,而end指向的是‘\0’,(即左闭右开区间【】)迭代器在使用时要特别注意:迭代器指向的内存空间是否发生了挪动或者释放,是否已经失效,下面举例

string s = "123456789";    
string::iterator it = s.begin();
s.erase(0,5);                  //删掉前五个数据
while (it != s.end())          //挪动数据了,但是没有失效
{
	cout << *it;
	++it;
}

//下面这个例子,是end迭代器在使用erase接口后,没有更新,仍旧指向原来的end,指向了一块非法内存,导致失效
string s = "hello world!";
string::iterator it = s.begin();
string::iterator end = s.end();     //迭代器失效
s.erase(0,3);                     
while (it != end)
{
	cout << *it ;
	++it;
}

//在交换后,由于s1和s2对应的内存大小不同,end指向了一块非法内存导致失效。
string s1 = "hello world";
string s2 = "change world";
string::iterator it = s1.begin();          //迭代器失效
swap(s1, s2);             
while (it != s1.end())
{
	cout << *it;
}
cout << endl;

Capacity系列函数:

在这里插入图片描述
string在存字符串的时候,只给出了有效字符串的大小位置,但是底层还是多开了了一个字节的位置去存‘\0’。

注意

  1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
  2. clear()只是将string中有效字符清空,不改变底层空间大小。
  3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。
    注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
  4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

其中最常用的就是reserve和resize,empty和clear,不同编译器下,为字符串预留出的空间是不同的,增容方法也是不同的,我们通过理解这些函数,即使面对不同编译器,也能正确的操作。

Modifiers系列函数

在这里插入图片描述
这一系列函数,主要包括增、删、改。

同样,介绍几个常用的以及容易出错的。

注意:

  1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
  3. erase采用的是左闭右开区间 [ ),默认从0开始到npos(size_t =-1)也就是无符号数全1,返回的是擦除后的string.

String operations系列函数

在这里插入图片描述
这一系列主要是用来查找的,查找字符,字符串,返回只为下标。

C_str返回C语言格式的字符串,即遇到‘\0’就结束。

substr是截取指定位置,返回的是截取位置的字符串

find系列找不到就返回npos。

非成员函数

在这里插入图片描述
这一部分涉及输入输出重载等,着重介绍一个比较常用的,从键盘输入字符串的时候,cin遇到空格就会停止,getline不会,录入一行字符串。
getline是可以指定分隔符的,在遇到‘\n’换行符时才停止。

string的相关习题

1.考察erase

输出的是什么?

string str = "Hello Bit.";
		string::iterator it = str.begin();
		while (it != str.end())
		{
			if (*it != ' ')
			{
				cout << *it;
			}
			else
			{
				str.erase(it);
			}
			it++;
		}

答案为Helloit,在删除空格后,空格后的数据向前挪动了一个字符的位置,it仍旧指向空格的位置,随之it++,跳过了B。

2.华为机试

链接: 题目链接.

此题考查getline函数。

模拟实现string

已经说了很多了,有需要和有兴趣的自取。
链接: 模拟实现string.

标签:字符,函数,STL,basic,字符串,size,---------,string
来源: https://blog.csdn.net/Zhou000815/article/details/115027453

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有