C++:string相关内容的简单介绍

news/2024/12/14 13:51:30/

目录

介绍:

string类的常见接口说明 

1. string类的常见构造

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

1.2  string(const char* s)

1.3  string (const char * s , size_t  n);

 1.4 string(size_t n,char c);

 2.string类对象的容量操作 

 2.1 size  与  length

2.2 capacity 

2.2.1 capacity的扩容机制 

2.3 clear 

2.4 reserve 

2.5 resize 

(1)字符串变短

(2)字符串变长 

(3)修改长度比capacity大 

3. string类对象的访问及遍历操作 

 3.1 operator[] 与 at

3.2遍历操作 

1.使用size 

2.使用operator[] 

3.begin + end 的 迭代器 遍历操作

3.1 反向迭代器 

4.string类对象的修改操作 

4.1push_back 

4.2 append 

4.3 operator +=  (最为常用) 

 4.4 assign

4.5 insert 

 4.6 erase

4.7 replace 

4.7.1 find与replace 

小总结: 


介绍:

  相关内容详细介绍:cplusplus.com/reference/string/string/?kw=string

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string string,所以string 在底层的本质上也是一个模板
  4. 不能操作多字节或者变长字符的序列。
  5. 在使用string类时,必须包含#include头文件以及using namespace std;

string类的常见接口说明 

1. string类的常见构造

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

void test_string()
{string s1;string s2(s1 , 5 ,10);
}提取字符串中的某个区间段的字符,作为一个新的字符串
或者可以说是从一个字符串中提取子字符串
  • str:要从中提取子字符串的源字符串。
  • pos:指定要开始提取子字符串的位置。
  • len:可选参数,指定要提取的子字符串的长度。默认值为 npos,表示提取从 pos 开始到源字符串的末尾的所有字符。

1.2  string(const char* s)

const char* cstr = "Hello, C++";
string str(cstr);  // 使用构造函数将字符串赋值给string的对象strcout << str << endl;  // 输出:Hello, C++接收一个char类型的字符串作为参数,也就是说将一个字符串赋予给string的对象 

1.3  string (const char * s , size_t  n);

const char* cstr = "Hello, World!"; 
size_t n = 5; 
std::string str(cstr, n); // 使用C风格字符串的前n个字符初始化std::string对象
  • 在这个例子中,cstr 指向字符串 "Hello, World!"。
  • 由于 n 被设置为5,std::string str(cstr, n); 会创建一个 std::string 对象 str并只包含 "Hello" 这5个字符,不包含后面的逗号和空格以及终止空字符。

 1.4 string(size_t n,char c);

string s6(10,'#');
cout << s6 << ednl;//输出结果 : ##########本质上是一种初始化

 2.string类对象的容量操作 

 2.1 size  与  length

void test_string()
{string s1("hello world");cout << s1.size() << endl; //输出结果: 11cout << s1.length() << endl; //输出结果: 11}size 与 length 的功能都是返回字符串的实际长度,二者并没有任何的区别

2.2 capacity 

void test_string()
{string s1("hello world");cout << s1.capacity() << endl; //输出结果: 15}返回字符串所处在的空间大小,在一般情况下capacity的返回值并不会包含\0所占用的空间

同时,我们需要直到的是capacity的返回值是比size和lenghth的返回值大的,理由如下:

在C++中,std::string是一个动态数组,它可以根据需要自动调整大小,当你创建一个字符串对象时,它会分配一定的内存空间来存储字符串的字符。

这个内存空间的大小由capacity决定,在例子中,字符串"s"的内容是"hello world",它包含11个字符,然而,为了提高性能,std::string通常会分配比实际字符串长度更大的内存空间。

这个额外的空间被称为capacity,它用于存储未来可能添加到字符串中的字符,以避免频繁的内存重新分配操作。所以,s.size()返回的是字符串实际包含的字符数,即11。而s.capacity()返回的是字符串当前分配的内存空间大小,即15。

2.2.1 capacity的扩容机制 

如上代码想要表达的意思如下:

  • 使用变量 sz 获取当前 字符串中的 空间大小,随后进入for循环中使用了 同为 string 的一种接口,push_back 对字符串内部的内容进行添加,随后,判断当前 sz 与 当前的capacity 大小相比较。
  • 由于,在字符串中添加了内容,以及在字符串内部添加了内容,导致了capacity 会因为字符串内容的添加进行空间的对策扩充。
  • 而这个扩充的机制便是,第一次扩充到原来空间的两倍左右,而之后则扩充到当前空间的1.5倍

2.3 clear 

void test_string()
{string s1("hello world");cout << s1  << endl; //输出结果: hello worlds1.clear();cout << s1  << endl; //输出结果:一行空格}清除数据,但仅仅只是数据的清除,空间并不一定清理掉
也就空间不会被释放或者空间不会被销毁!只是清除了空间内部的数据void test_string()
{string s1("hello world");cout << s1  << endl; //输出结果: hello worldcout << s1.capacity() << endl ; // 输出结果:15s1.clear();cout << s1  << endl; //输出结果:一行空格cout << s1.capacity() << endl;//输出结果:15
}如果想要释放空间或者在情况数据后释放空间,可以使用shrink_to_fit
但是这个只是缩小空间大小,但还是会保留一定量的空间,总之不会变成0

2.4 reserve 

string s;//创建一个string 的变量s
s1.reserve(100);//提前为 s 进行空间的开辟
cout << s1.capacity() <<endl;//输出结果是 111reserve的功能是开辟空间,或者说是预留空间
当我们知道所需要的空间大小时,可以使用reserve进行空间的开辟
使得在内存空间中提前为我们需要的数据开辟空间当然,使用了reserve后,因为编译器的问题,有些编译器为了灵活分配内存空间问题
会对reserve开辟的空间进行二次的开辟,也就说进行空间的二次预留这样就导致开辟出来的空间可能比我们需要的空间还要多

同时,如果使用了reserve 进行空间的扩容,是完全可以的,但是要注意,reserve进行扩容的大小必须要比当前空间的大小还要大,不然reserve是无效扩容 

void test1()
{string s1("hello world xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")cout << s1.capacity() << endl;s1.reserve(10);cout << s1.capacity() << endl;//因为reserve扩容的大小比capacity小,所以扩容无效}void test2()
{string s1("hello world xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")cout << s1.capacity() << endl;s1.reserve(200);cout << s1.capacity() << endl;//因为reserve扩容的大小比capacity大,所以扩容成功//输出的结果,应该是两百左右的大小}

2.5 resize 

resize的主要作用是改变一个字符串的实际长度,但是resize改变长度的情况分为三种:

(1)字符串变短
string s("hello world");
cout << s.size() << endl; // 长度是 11
sout << s.capacity() << endl; // 空间大小是 15s.resize(5);
cout << s.size() << endl; //长度是5
sout << s.capacity() << endl;//空间大小是15

当resize修改的长度比原本的长度还要小时,那么resize会保留前面的长度,删除后面的数据内容,以此达到相对因的长度,不包含\0 

(2)字符串变长 
string s("hello world");
cout << s.size() << endl; // 长度是 11
sout << s.capacity() << endl; // 空间大小是 15s.resize(13);
cout << s.size() << endl; //长度是13
sout << s.capacity() << endl;//空间大小是15

当resize修改的长度比原本的长度还长,且resize修改的长度比capacity的空间大小要小时,字符串的长度会被添加至resize修改的长度,而多出来的部分则是用\0进行填充,或者被指定字符填充,以上的代码是默认情况,使用了\0填充 

(3)修改长度比capacity大 
string s("hello world");
cout << s.size() << endl; // 长度是 11
sout << s.capacity() << endl; // 空间大小是 15s.resize(20);//修改的长度比空间大小还大
cout << s.size() << endl; //长度是20
sout << s.capacity() << endl;
//空间大小是31,因为修改长度超过了原来的空间大小,所以进行了扩容

当resize修改的长度大小比capacity还要大时,capacity会进行扩容处理 


3. string类对象的访问及遍历操作 

 3.1 operator[] 与 at

void test()
{string s1("hello world");cout << s[2] <<endl; //结果是 ecout << s.at(2) << endl; //结果是 e}

 at和[]的功能是类似的,二者虽然访问的功能是一样的,但是二者的检查越界的方式是不一样的。

如以上两张图,图1是[]的越界访问,是一个断言警告,图二是at的越界访问,是一个异常处理 

3.2遍历操作 
1.使用size 

2.使用operator[] 

而由于operator []的本质是返回当前位置的字符,所以可以利用它的特性对字符串中的字符进行++或者--等相关的加减操作

3.begin + end 的 迭代器 遍历操作

迭代器的行为像指针一样的类型对象,begin是返回第一个有效位置的迭代器,end是返回最后一个有效数据的下一个位置,这里的最后一个有效数据的下一个字符是\0,相当于指针的移动,从当前位置移动到\0位置结束

时使用迭代器也可以进行字符串中的字符修改操作  

3.1 反向迭代器 

 反向迭代器使用的是 rbegin 和 rend 进行字符串的反向输出操作 


4.string类对象的修改操作 

4.1push_back 

主要功能是在字符串的尾部插入字符,且只能插入一个字符 

void test()
{string s("hello world");s.push_back("!");cout << s << endl; //输出结果:hello world!}

4.2 append 

append(const & char*s)这个功能和push_back的功能类似,但是比push_back更强,因为它可以添加字符串

void test()
{string s("hello world");s.append(" hello bit");cout << s << endl; //输出结果:hello world hello bit}

4.3 operator +=  (最为常用) 

void test()
{string s("hello world");s += " " ;s += "apple" ;cout << s << endl; //输出结果:hello world apple}

 4.4 assign

 最常见的功能是字符的覆盖,将空间内部内容进行删除,然后在添加所需要的内容

void test()
{string s("hello world");s.assign("xxx");cout << s << endl; //输出结果:xxx}

4.5 insert 

 主要功能在当前位置之前插入字符串

void test()
{string s("hello world");s.insert(0,"xxx");cout << s << endl; //输出结果:xxxhello world}

 4.6 erase

 从某个位置开始删除几个字符,如果字符不够删,则有多少删多少

void test()
{string s("xxxhello world");s.erase(0,3);//前面的 0 是位置,后面的3是需要删除的字符个数cout << s << endl; //输出结果:hello worlds.erase();cout << s << endl;//erase的默认是全部删除,只留下一行空格当作还要空间存在没有释放}

4.7 replace 

 主要功能是字符的替换,某个区间位置的字符进行替换

void test()
{string s("hello world");s.replace(5,1,"%")//5是位置,1是替换的字符个数,%是替换的内容cout << s << endl; //输出结果:hello%world}

4.7.1 find与replace 

find的功能是寻找字符串内部需要查询的字符,找到后返回字符所处在的位置下标,找不到则返回-1

如图配合了replace使用,就可以查询字符串中的空格符号,并且将空格符号进行替换,直到字符串内的所有空格符号都替换完成,其中的npos其实表示的是find找不到字符后的返回值。也就是-

小总结:

insert replace erase 这几个能少用就少用,因为基本都需要挪动数据,它们的底层代码就是挪动数据,所以效率不是很高,建议多使用operator += 


 


http://www.ppmy.cn/news/1364703.html

相关文章

cesium相机视角跳转和缩放至entity方法汇总

下面汇总的相机视角跳转方法有很多种&#xff0c;都是根据某一个经纬度高程坐标[x,y,z]&#xff0c;Entity实体或者矩形四至范围[west , south , east , north]作为视图跳转到目标范围的中心&#xff0c;然后在该位置上设置相机相对的偏移量&#xff0c;这个偏移量主要是设置相…

分享便携式血氧仪单片机方案

血氧仪主要测量指标分别为脉率、血氧饱和度、灌注指数。血氧饱和度是临床医疗上重要的基础数据之一。以家用指压式血氧仪为例&#xff0c;一个血氧仪一般由MCU、存储芯片、两个控制LED的数模转换器、两个发光二极管驱动等组成。 灵动微电子的MM32MCU产品已被广泛地应用在了一些…

单词倒排——c语言解法

以下是题目&#xff1a; 这个题中有三个点&#xff0c; 一个是将非字母的字符转换为空格&#xff0c; 第二是如果有两个连续的空格&#xff0c; 那么就可以将这两个连续的空格变成一个空格。 第三个点就是让单词倒排。 那么我们就可以将这三个点分别封装成三个函数。 还有就是…

解决i18n国际化可读性问题,傻瓜式webpack中文支持国际化插件开发

先来看最后的效果 问题 用过国际化i18n的朋友都知道&#xff0c;天下苦国际化久矣&#xff0c;尤其是中文为母语的开发者&#xff0c;在面对代码中一堆的$t(abc.def)这种一点也不直观毫无可读性的代码&#xff0c;根本不知道自己写了啥 &#xff08;如上图&#xff0c;你看得出…

Linux------进程地址空间

目录 一、进程地址空间 二、地址空间本质 三、什么是区域划分 四、为什么要有地址空间 1.让进程以统一的视角看到内存 2.进程访问内存的安全检查 3.将进程管理与内存管理进行解耦 一、进程地址空间 在我们学习C/C的时候&#xff0c;一定经常听到数据存放在堆区、栈区、…

《opencv实用探索·二十二》支持向量机SVM用法

1、概述 在了解支持向量机SVM用法之前先了解一些概念&#xff1a; &#xff08;1&#xff09;线性可分和线性不可分 如果在一个二维空间有一堆样本&#xff0c;如下图所示&#xff0c;如果能找到一条线把这两类样本分开至线的两侧&#xff0c;那么这个样本集就是线性可分&#…

C++:类与对象(2)

创作不易&#xff0c;感谢三连&#xff01; 一、六大默认成员函数 C为了弥补C语言的不足&#xff0c;设置了6个默认成员函数 二、构造函数 2.1 概念 在我们学习数据结构的时候&#xff0c;我们总是要在使用一个对象前进行初始化&#xff0c;这似乎已经成为了一件无法改变的…

mapbox高德地图与相机

本案例使用Mapbox GL JavaScript库创建高德地图。 文章目录 1. 演示效果2. 引入 CDN 链接3. 创建地图3.1. 定义地图数据源3.2. 配置地图图层 4. 设置地图样式5. 实现代码 1. 演示效果 2. 引入 CDN 链接 <script src"https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbo…