当前位置: 首页 > news >正文

C++【string类的使用】(上)

文章目录

  • 1. 为什么要学习string类
  • 2. 标准库的string类
    • 2.1 string的构造函数
      • (1)无参构造(重点)
      • (2)用字符串初始化(重点)
      • (3)用字符串的前n个字符初始化
      • (4)拷贝构造(重点)
      • (5)拷贝str的一部分
      • (6)拷贝n个字符
      • (7)用迭代器初始化
    • 2.2 string的访问及遍历
      • 1. operator[]
      • 2.Iterators(迭代器遍历)
        • 反向迭代器
      • 3. 范围for遍历
        • auto关键字
        • 范围for遍历
    • 2.3 string的容量操作
      • 1.size和length(size是重点)
      • 2. max_size
      • 3. capacity
      • 4. resize(重点)
      • 5. reserve(重点)
        • 补充
      • 6. clear
      • 7. empty
      • 8. shrink_to_fit
  • 结语

1. 为什么要学习string类

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

在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数。

2. 标准库的string类

string类的文档介绍
在这里插入图片描述
在使用string类时,必须包含#include头文件以及using namespace std;

2.1 string的构造函数

在这里插入图片描述

(1)无参构造(重点)

C++为了与C语言的<string.h>区分开,是不会加 .h 的(C++的头文件<string>

string();

无参构造的string内是没有元素的。

#include<iostream>
#include<string>using namespace std;void test_string_Construct()
{string s1;cout << s1 << endl;
}

在这里插入图片描述
注意:我们这里是使用的<<是string类实现的全局输出函数(string类还实现了>>输入函数)
在这里插入图片描述

(2)用字符串初始化(重点)

string (const char* s);

文档内容:
Copies the null-terminated character sequence (C-string) pointed by s.

将C字符串拷贝给对象。

string s2("Hello World");

在这里插入图片描述

(3)用字符串的前n个字符初始化

string (const char* s, size_t n);

拷贝C字符串的前n个字符到string类的对象

string s3("Hello World", 5);

在这里插入图片描述

(4)拷贝构造(重点)

string (const string& str);

一个str初始化一个新对象

	string s2("Hello World");string s4(s2);

在这里插入图片描述

(5)拷贝str的一部分

string (const string& str, size_t pos, size_t len = npos);

pos为拷贝的开始位置,len为拷贝的字符个数,npos是string的成员常量
在这里插入图片描述
代表如果没给拷贝的字符个数,默认拷贝到str的\0

没有给要拷贝的个数

	string s5(s2, 6);cout << s5 << endl;

在这里插入图片描述
给了拷贝的个数

	string s6(s2, 6, 3);cout << s6 << endl;

在这里插入图片描述

(6)拷贝n个字符

string (size_t n, char c);

用n个字符拷贝初始化str

	string s7(5, 'x');cout << s7 << endl;

在这里插入图片描述

(7)用迭代器初始化

template <class InputIterator>string  (InputIterator first, InputIterator last);

按相同顺序复制范围 [first,last] 内的字符序列。

	string s2("Hello World");string s8(s2.begin(), s2.end());cout << s8 << endl;

在这里插入图片描述

2.2 string的访问及遍历

1. operator[]

在这里插入图片描述
返回string类中第pos位置的引用,也支持const string类调用(但权限是只读)

	string s1("Hello World");//下标+[]遍历//普通对象for (int i = 0; i != s1.size(); i++){s1[i] += 2;cout << s1[i] << ' ';}cout << endl;//const对象const string s2("Hello World");for (int i = 0; i != s1.size(); i++){//s1[i] += 2;cout << s1[i] << ' ';}

在这里插入图片描述

const对象这样操作会报错(权限只有只读)
在这里插入图片描述

2.Iterators(迭代器遍历)

STL六大组件之一,这里只讲一些迭代器的用法,后期我们会详细讲解。
在这里插入图片描述

在这里插入图片描述
返回一个指向string第一个字符的迭代器

	string s1("Hello World");string::iterator sit = s1.begin();

分析下上面的代码,我们先突破了string类域,指定了iterator 定义了变量 sit,然后 sit 接收了来自s1.begin()的返回值,也就是指向第一个字符的位置。
从这里我们可以感觉到这个迭代器的功能特别像指针,但是!迭代器不一定是指针,因为迭代器不仅仅是数组类数据结构有,而是STL的数据结构都有迭代器的功能,像map结构,list结构他们都有迭代器,而且所有迭代器还支持++和解引用,这些迭代器都是重载过的,当然我们也可以把他当作指针用,因为它的用法和指针十分相似。
在这里插入图片描述
返回一个指向最后一个字符的迭代器('\0'
在这里插入图片描述

	//迭代器遍历string s1("Hello World");string::iterator sit = s1.begin();for (; sit != s1.end(); sit++){cout << *sit << ' ';}cout << endl;

在这里插入图片描述
我们也可以使用迭代器对s1进行修改
在这里插入图片描述
如果你只希望迭代器进行“读”的操作,不进行“写”的操作,那就可以使用const迭代器
在这里插入图片描述
在这里插入图片描述
const迭代器,功能和迭代器一样,只是没有了“写”的权限,

	string::const_iterator cit = s1.begin();while (cit != s1.end()){cout << *cit << ' ';cit++;//(*cit)++;}cout << endl;

在这里插入图片描述

反向迭代器

顾名思义,迭代器的方向是反方向的,这也就证明了迭代器并不是指针,指针是无法通过++来往后走的。
在这里插入图片描述
在这里插入图片描述

Returns a reverse iterator pointing to the last character of the string (i.e., its reverse beginning).
返回一个反向迭代器,这个迭代器指向string的最后一个字符的前一个位置(最后是'\0'


Reverse iterators iterate backwards: increasing them moves them towards the beginning of the string.
反向迭代器向后迭代:增加迭代器会使其向字符串的开头移动。

在这里插入图片描述

Returns a reverse iterator pointing to the theoretical element preceding the first character of the string (which is considered its reverse end).
返回一个反向迭代器,指向字符串第一个字符(被视为其反向末端)之前的理论元素。


The range between string::rbegin and string::rend contains all the characters of the string (in reverse order).
rbegin和rend之间的顺序是相反的

这里还有最有一种迭代器,const反向迭代器,理解了前面的const迭代器和反向迭代器,就能知道该怎么用了,这里就不赘述了
在这里插入图片描述

补充:const迭代器都是C++11加入进来的。

3. 范围for遍历

C++11支持更简洁的范围for的新遍历方式

auto关键字

在这里补充2个C++11的小语法,方便我们后面的学习。

  • 在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量后来这个不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。(也就是自动推导类型)

就拿迭代器来说,我们如果要写一个反向迭代器,我们需要写
string::reverse_iterator rit = s1.rbegin();
但是如果我们用了auto,那就不用写那么长的代码
auto resit = s1.rbegin();

  • 用auto声明指针类型时,用auto和auto*没有任何区别但用auto声明引用类型时则必须加&
  • 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
  • auto不能作为函数的参数,可以做返回值,但是建议谨慎使用
  • auto不能直接用来声明数组
范围for遍历

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。

范围for可以作用到数组和容器对象上进行遍历

范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到。

在这里插入图片描述

我们也可以不通过汇编来看(错误使用范围for的e)
在这里插入图片描述

2.3 string的容量操作

在这里插入图片描述

1.size和length(size是重点)

在这里插入图片描述
size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。

	string s1("hello worldxxxxxxx");//求元素个数cout << "size:" << s1.size() << endl;cout << "length:" << s1.length() << endl;

在这里插入图片描述

2. max_size

在这里插入图片描述

Returns the maximum length the string can reach.
返回string能到达的最大长度

	string s1("hello worldxxxxxxx");//返回string的最大长度cout << "max_size:" << s1.max_size() << endl;

32位环境下是21亿多
在这里插入图片描述
64位就更长的(达到了九十多亿万亿)
在这里插入图片描述

3. capacity

在这里插入图片描述

Returns the size of the storage space currently allocated for the string, expressed in terms of bytes.
返回当前空间所分配的大小(以字节为单位)

这个我们就很熟悉,也就不多讲解了

	string s1("hello worldxxxxxxx");//求容量大小cout << "capacity:" << s1.capacity() << endl;

在这里插入图片描述

4. resize(重点)

在这里插入图片描述

Resizes the string to a length of n characters.
将size修改到n


If n is smaller than the current string length, the current value is shortened to its first n character, removing the characters beyond the nth.
如果你给的n比原来的size小,那么会将当前值缩短为前 n 个字符,并删除 n 个字符之后的字符。


If n is greater than the current string length, the current content is extended by inserting at the end as many characters as needed to reach a size of n. If c is specified, the new elements are initialized as copies of c, otherwise, they are value-initialized characters (null characters).
如果你给的n比原来的size大且指定了字符c,新元素将被初始化为 c 的副本,否则,它们将是值初始化字符(空字符)。

	string s1("hello worldxxxxxxx");cout << endl << "改变内容个数:" << endl;//改变内容个数s1.resize(s1.size() - 5);	   //小于原本的size会删除string内部的元素(从后往前删)cout << s1 << endl;cout << "size:" << s1.size() << endl;cout << "capacity:" << s1.capacity() << endl << endl;//减少了size并不会减少capacitys1.resize(s1.size() + 5);	   //大于原本的size,会在多余的地方加入'/0'cout << s1 << endl;cout << "size:" << s1.size() << endl << endl;s1.resize(s1.size() + 2, '#'); //大于原本的size且指定了字符,会在尾部插入n个指定字符cout << s1 << endl;cout << "size:" << s1.size() << endl << endl;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. reserve(重点)

reserve改变的是capacity。
在这里插入图片描述

Requests that the string capacity be adapted to a planned change in size to a length of up to n characters.
要求将字符串容量调整为不小于size的长度,以适应计划中的大小变化。


If n is greater than the current string capacity, the function causes the container to increase its capacity to n characters (or greater).
如果 n 大于当前字符串容量,该函数会使容器的容量增加到 n 个字符(或更多)。


In all other cases, it is taken as a non-binding request to shrink the string capacity: the container implementation is free to optimize otherwise and leave the string with a capacity greater than n.
在如果给的数字在size与capacity之间,那么缩减字符串容量的请求就不一定会执行:容器实现可以自由地进行其他优化,使字符串容量大于 n。


This function has no effect on the string length and cannot alter its content.
这个函数无法影响string的size和修改string的内容

	string s1("hello");//改变容量s1.reserve(4);//容量比size小cout << "capacity:" << s1.capacity() << endl; //不会缩容(这里不管vs还是g++都不会缩容)s1.reserve(10);//改变的值在capacity与size之间cout << "capacity:" << s1.capacity() << endl; //在vs平台下不会缩容(但是在g++里会缩容)s1.reserve(20);//改变的值比capacity大cout << "capacity:" << s1.capacity() << endl; //会扩容

在这里插入图片描述

补充

补充一个小知识点,从上面的代码我们得知,只有5个元素的string竟然开了16个空间(多出来个是给'\0'

这是因为vs在设计string类时,设计了两个存储空间,当capacity小于16个时存储在有16个字节大小的_Buf数组里面当capacit大于16时再存储到堆上开辟的动态内存

在这里插入图片描述
当我们把size或者capacity修改到大于16时,数据就会存储到_Ptr里面。

6. clear

清空有效字符
在这里插入图片描述

Erases the contents of the string, which becomes an empty string (with a length of 0 characters).
清空string的内容,并将string的size置为0

	string s1("hello worldxxxxxx");//清除string的元素s1.clear();cout << "size:" << s1.size() << endl;          //归零cout << "capacity:" << s1.capacity() << endl;  //不变

在这里插入图片描述
clear()只是将string中有效字符清空,不改变底层空间大小。

7. empty

在这里插入图片描述
这个就是判断string是否为空

	string s1("hello worldxxxxxx");//判断string是否为空s1.clear();cout << s1.empty() << endl;s1 += 'a';cout << s1.empty() << endl;

在这里插入图片描述
判断的是string类的size是否为0

8. shrink_to_fit

这是C++11新加入的函数
在这里插入图片描述

Requests the string to reduce its capacity to fit its size.
要求string的capacity减少到size的大小


The request is non-binding, and the container implementation is free to optimize otherwise and leave the string with a capacity greater than its size.
该请求是非约束性的,容器实现可以自由地进行其他优化,使字符串的容量大于其大小。(但vs会执行)


This function has no effect on the string length and cannot alter its content.
这个函数无法影响string的size,也无法改变string的内容

	string s1("hello worldxxxxxx");cout << "capacity:" << s1.capacity() << endl;//将capacity缩减到sizes1.resize(10);s1.shrink_to_fit();cout << "capacity:" << s1.capacity() << endl; //缩小了

在这里插入图片描述

结语

如果全部讲解就会篇幅过长,所有剩下的部分会放在下半部的博客
那么这次的分享就到这里结束了~
最后感谢您能阅读完此片文章~
如果您认为这篇文章对你有帮助的话,可以用你们的手点一个免费的赞并收藏起来哟~
如果有任何建议或纠正欢迎在评论区留言~
也可以前往我的主页看更多好文哦(点击此处跳转到主页)。


http://www.mrgr.cn/news/57907.html

相关文章:

  • 多线程初阶(七):单例模式指令重排序
  • RAG技术
  • 决策树(Decision Tree)
  • python+docxtpl:word文件模版渲染
  • ArcGIS002:软件自定义设置
  • kotlin 中 ::class ::class.java 和 .javaClass 区别
  • 数据挖掘示例
  • 基于Java的就业信息管理系统源码带本地搭建教程
  • windows|常见的文件伪装方法
  • 如何使用 Maven 不同环境使用不同资源文件 提升项目安全性
  • vue通过JSON文件生成WPML文件源码
  • 【1024】程序员未来的路在那里
  • kafka 如何减少数据丢失?
  • Bash 中的 ${} 和 $() 有什么区别 ?
  • 最基础Lua语法教程,一看就会!(下篇)
  • 车辆自燃后除了找保险公司赔偿,还能以产品质量缺陷为由起诉厂家吗?
  • 从0开始学python-day14-pandas1
  • 案例分析-系统开发基础
  • txt文件怎么加密?2024年txt文件加密最简单的方法,共3个!一分钟学会!
  • 使用 STM32F407 串口实现 485 通信
  • # TOGAF技术架构:小白也能看懂的指南
  • 【github小问题】——push后报错error: src refspec master does not match any
  • 爆肝整理14天!AI工具宝藏合集
  • 一文掌握 jetbrains IDE 新 UI,还不会新 UI 的同学快看过来
  • 还有谁不会解决农夫过河问题
  • 教程分享!超简单的低功耗4G模组LCD应用示例!看过来~