c++ string类使用

为了解决 C 语言中字符串处理的缺陷,并提供更安全、高效、易用的字符串操作方式  所以c++委员会在std标准命名空间里面创建一个字符串类string  在类中实现了很多的功能可以让我们直接使用

大概如下图结构

然后在string类中写了非常多的成员函数 运算符重载等对外实现了大量功能的接口  

string类对象的常见构造

test

赋值重载

test

如下图 在定义的时候直接赋值这样不是调用了赋值重载  右边的char类型的x是先要通过string类的构造函数隐式转换为string类类型  再通过上述的赋值重载进行赋值 但是构造函数没有一个字符的构造函数 就报错了

通过构造函数和赋值重载可以发现  功能设计的时候有些冗余了  很多功能都是重的 char*类型也能隐式转换string     其实是为了兼容c

string类对象的容量操作

这些都是string类的成员函数

size和length功能都是返回字符的个数  只不过最开始是用的length 后来发现如在树那块等用length来表示就不合理了 用size来表示比较合理 但是也没有吧length给删掉   建议使用size

capacity 返回容量

max_size  用于返回字符串理论上的最大长度  这个和系统内存 实现限制都有关

resize函数用于调整字符串的大小(长度)

n小于当前字符串长度,会截断字符串,保留前n个字符。

n大于当前字符串长度,会在字符串末尾添加值为0char类型字符,使字符串长度达到n

第二个参数可以为字符类型 如果n大于字符串长度的话就会以该字符填充

如下 第二个 默认的字符0在字符串中是结束标准 cout不会打印出来

empty

检测字符串释放为空串,是返回true,否则返回false

clear

清空有效字符  不改变底层空间大小

 

npos

在 C++ 中,string::npos 是 string 类的一个静态常量成员,表示“不存在的位置”“无效的索引”。它通常用于字符串搜索、子字符串操作等场景,表示未找到匹配项或超出有效范围。

由于 size_t 是无符号类型,-1 会被转换为它的最大值

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

重载[]

string类型可以像数组一样用下标访问及进行修改 就是用到了运算符重载 返回了char类型的引用

迭代器

在c++中提供了一些迭代器

迭代器在理解上现在暂时可以看作类型指针一样 但不是真的指针

begin()相当于指向的就是第一个位置  end()相当于指向的是最后一个字符的后一个位置 也就是 /0

所有的容器都可以用类型这种方式进行访问

反向迭代  rbegin()指向倒数第一个位置 rend()指向第一个字符的前一个位置 但是里面ii还是++的方式  也证明了不是指针

迭代器有四种  根据带不带const 和带不带 reverse划分

auto

auto本来是一个已经被废弃掉的关键字  c++11中对其进行重定义 使其变废为宝 

现在auto 如int double 一样 是类型 不过它可以自动识别是什么类型 

如刚刚的迭代器或者int double 等都可以自动识别

其实 auto 基本没什么用到的地方也  就是在简化代码方面有些用处   如一个类型很长 如std::string::iterator等等 写起来比较麻烦就可以用auto  当然随之代码可读性降低了

auto可以做返回值(不建议 如果多层调用都是auto 不知道参数是什么类型)  不可以作为函数的形参类型 也不可以作为数组的类型

遍历string方式

1. 通过重载过的[]进行下标访问

2.迭代器方式

3.范围for

范围for

在c++11出现  用于需要全部遍历

for循环后的括号由冒号“ :分为两部分:第一部分是范围 内用于迭代的变量,第二部分则表示被迭代的范围   

底层用到的其实就是迭代器  自动赋值,自动迭代,自动判断结束

要注意 如果要改变内容 引号左边的内容要引用

string类对象的修改操作

插入

push_back 一次只能尾插一个字符

如下图 不断尾插c 当空间不够的时候会自动扩容(在string类中已经写好  后面的中间插入其实都会自动扩容和移动位置)

扩容空间问题

对于vs下的 初始的容量为15 其实空间为16(有一个/0占一个空间)容量只算能存的空间为15  空间不够时第一次扩容 扩容到原来的2倍为31其实是16*2然后/0占一个 之后都是1.5倍的扩容

为什么vs下第一次是15呢  其实在string中 有一个是存放16个字符的数组 一个字符指针  当字符小于等于16的时候就用第一个_Buf来存储 当超过16的时候就用_Ptr来存储 

对于linux下的 gcc编译器初始没有空间 第一次开一个空间 之后每次为上一次二倍的方式扩容

这时候可以用到以下函数reserve  

用于提前分配内存,以优化字符串操作时的性能,避免频繁的内存重新分配

如下  这样就避免了扩容的消耗

这为什么是112个空间呢呢 其实是因为对齐原则

既然reserve会自动预留空间 如果预留的空间小于容量会缩容吗  

对于vs来说

当预留空间小于size和大于size小于capacity的情况下都不会扩容 而对于大于capacity的情况会进行扩容

而对于linux下的gcc而言

当预留空间小于size时候容量如果此时大于size 容量会缩小到和size一样大 当预留空间大于size  小于容量时会扩容  当大于capacity会扩容

append

用于在一个字符串尾部插入字符  同样也是为了c的兼容搞了一堆char*的还

 重载+=

+=test

重载的+= 其实就可以不用push_back 和append了基本 很多设计的确实有些麻烦了

insert

insert相较于上面的插入主要区别在于可以选择插入的位置

inserttest

删除

erase

第一行的  第一个参数时删除开始的位置 默认缺省值为第一个位置 第二个参数为删除的长度 默认缺省值全删   都不写的话就会全部删掉

erasetest

可以看到删除在vs下也并不会缩容

替换

replace

test

如果要让一个字符串中的空格全部替换为***  我们可以要到find结合replace来实现

查找

find

第二个参数没有默认从第一个位置开始找  如果没有找到返回npos (最大值)

如下 用find和replace就可以解决刚刚的把所有的空格都替换为***的问题 

 但是还有个问题 对于replace如果是一个位置替换为多个字符 其实会进行将右边数据整体后移 当多个位置替换为少个后面的又会整体左移   如果有很多的空格 这样会有很多的消耗

另一种方法   再创建一个字符串ss 遍历s4不是空格ss就加该字符 是字符ss+=*** 

rfind

类似于find rfind是从后往前找  

可以用于找文件的后缀  不过还需要用到一个函数 substr

用于返回字符串的部分子串   第一个参数没有默认缺省值从0开始  第二个参数没有默认缺省值nops到字符串的末尾

用rfind和substr就可以解决 找文件后缀的问题了  用find如果前面文件名有.就出问题了

这和find的区别在于可以同时对好几个字符同时处理 如下图

找到abcdef中的任何一个都会返回size_t类型  然后替换为* 

对应的其他也都差不多  last就是从后开始找  加了not就是不是里面内容的返回

c_str()

该函数返回一个指向以空字符结尾的字符数组的指针,这个字符数组存储了与 string 对象相同的字符序列const 关键字表示返回的指针指向的内容是只读的,不能通过这个指针修改字符串内容。

生命周期问题:返回的C风格字符串指针的生命周期与 string 对象相关联。如果 string 对象被修改或销毁,那么之前通过 c_str() 获取的指针将不再有效,继续使用该指针可能会导致未定义行为。

只读性:由于返回的指针是 const char* 类型,不能通过该指针修改字符串内容。如果需要修改字符串,应该直接操作 string 对象。

为了兼容c而存在  接收到之后不能自己改变  会随着原来string中字符串的改变自动改变  生命周期也和原来string字符串相同

string大小

从上述图片知道   不管string类型有多次 sizeof算的字节数都是40个 (当然这和编译器及x86 x64都有关)

这其实是 16+8+8+8所得到的 

之前提到了 在vs下string类里会有一个char ar [16] 这样的数组 和一个 char* ar2类型的指针 当字符小于16存在数组中  大于16的时候存在指针当中  

这里的数组占了16个字节 x64下指针占了8个字节 此外还有size_t类型的size和capacity分别占了8个字节 所以一共占了40个字节

当换成x86下 就是16+4+4+4wield28个字节了

getline

对于cin来说 当读取到空格或者是换行都会结束 所以无法往s1中直接输入空格

使用getline的方式就可以解决了

getline还可以有第三个参数    如果第三个参数写了 那么会一直读取 直到读取到这个参数然后结束

如果没有的话就默认读取到换行结束

这里第三个参数为*  则会一直读取直到读取到*为止  否则会一直读取输入的数据 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值