string1
引用
- std:string
前言
回忆过C语言版的字符串
1 | char ch[] = "abafjiafajif"; |
大致上一个意思,限定长度和不限定长度,不限定长度会自动根据初始化的值长度而定义。
其次就是拼接两个字符串
1 | char ch[10] = "1234"; |
这样拼接起来还是挺麻烦的,如果能直接相加赋给字符串就会相对方便了。
正文
1 |
|
使用string关键字前需包含头文件string,此外如果不想老是写std::string,就在下面加一句using std::string;
.
1 | string str = "hello world"; |
定义起来格式就跟正常变量一样。输入输出相较于C语言类型的字符串的好处就是,不用提前声明大小,不用担心随便溢出。
此外string还可以指定只接受字符串的一部分
1 | string str{ "hello world" , 5}; |
除了从0开始,还能自定义:
1 | string str = { "hello world" , 1,3}; |
能从指定的字符串获取,也就能从变量获取
1 | string str; |
像比较之下方便了许多,但是这其实也就是官方封装好的,自己也能实现类似的效果
ps:对中文支持一般,因为字符集的不确定性,不能保证不同占用下带来的问题
还有一种比较无聊的写法:
1 | string str(6,'a'); |
就是赋值了6个’a’组成的字符串。
然后回到拼接字符串,string可以直接通过相加实现
1 | string str = "1234"; |
效果也是ok的。
当然要求+的时候都是字符串,不能是字符串以外的东西
如果想加一串数字,那也只能先将其转换成字符串。
1 | string str = to_string(123); |
这样得到的str就是“123”
,一个字符串类型的变量。
当然数字不单只是整型的,小数也可以。
加强
字符串拼接存在一个问题,那就是参数不能都是常量
1 | string str; |
这种情况下就会报错,原因是这两个常量“123”和“456”在计算机里还是char类型的
解决办法可以创建临时变量或者强转
1 | string str; |
如果使用+=
操作符,那么也要注意类型转换,因为+的优先级高于+=
1 | string str; |
append
之前的拼接都是使用+号,还得额外创建一个变量,string本身提供了一种方法就是append
1 | string str = "123"; |
同时append可以套娃str.append("123").append("456").append("789").....
也可以截取str.append("123456",3)
或者str.append("123456",2,5)
也可以使用定义时的办法str.append(6,'a')
抛开使用中的一种,也就意味着append有七种参数方法。
substr
字符串的截取方法
1 | .substr(index,end); //输入截取的起点和终点 |
substr会有一个返回值,返回的值就是截取后的字符串,可以用于赋值给其他字符串或者直接打印
1 | string str = "0123456789"; |
效果就是:
length
C语言我们计算字符串长度使用strlen
,cpp的string则也有计算长度的方法length
1 | string str = "0123456789"; |
效果就是:
当然length的返回值也可以赋值给一个int类型的变量,以作重复使用。
然后同样的问题,对中文的支持都是很玄学,毕竟各字符集对中文占用大小并不统一
[]
string也可以通过[]去访问字符串成员,下标依然0起,底层实现也是类似的,使用的内存空间也是连续的。
就没什么必要演示了
判断
1 | char *ch = (char*)"123456"; |
在C语言里,字符串其实没有一个很准确的比较功能,像上述的代码中,能够判断也是因为二者的初始化时相当于使用了常量,而编译器恰好优化了常量,使常量的地址一致,所以才会判断相等
结果就是:
反汇编看两个初始值的情况
可以看到”123456“的十六进制值是相同的,所以比较的时候才相等。
但是这种比较方法很显然不靠谱。防止编译器优化的话,就需要其中一个字符串通过手动输入,这样就不能一下子确认为是常量。
但其实也有一个方法strcmp,不过就得借用string.h头文件了,也就是变相借助了工具,所以说原生下没有这种功能。int strcmp(const char* str1,const char* str2);
返回值:
- 如果返回值 < 0,则表示 str1 小于 str2。
- 如果返回值 > 0,则表示 str2 小于 str1。
- 如果返回值 = 0,则表示 str1 等于 str2。
而string的话,它肯定是内置了不少方法的:== != > < >= <=
原则就是根据顺序,依次比较字符大小,在第一个字符就分出大小则就无视后面的字符,如果第一个字符相等就往后比较以此类推。
compare
string类型自带的方法,返回值是int类型的值
- 两个字符串完全相等返回0
- 相比比较的字符串小返回负数
- 相比比较的字符串大返回正数
所以if的时候要注意,因为使用compare如果相等返回的是0,0在C语言cpp里面是表示假的。
.compare(index, end, str)
这是一个拓展的参数,可以指定被比较的字符串从哪里开始到哪里结束。
find
.find(str)
,find的返回值是一个整型,它可以找到str第一次出现的下标。
使用场景的话,最常用的就是substr的时候,找到原字符串内的某一块内容,用find当起始值。.find(str,index)
从要比较的字符串的index处包括index开始查找,返回值是std::string::npos 可能是-1或者4294967295.find(str,index,end)
从要被比较的字符串index处开始查找,范围是{str[0],str[end]}
rfind
这玩意。。就是倒着搜的find。
所以指定index的时候要从最后面开始,从0开始没遇到直接就罢工了。。
这玩意用的真的挺少的感觉。
insert
string的插入方法,参数小多.insert(要插入的位置,要插入的字符串,要插入的字符串起始位置,要插入的大小);
.insert(要插入的位置,要插入的字符串,要插入的大小);
1 | string str = "abc,"; |
replace
string的内置方法,可以指定替换string中的内容.replace(index, length, "str")
.replace(index, length, "char length", char)
.replace(起始位置,要替换长度,替换内容,替换后容节选长度)
.replace(起始位置,要替换长度,替换内容,替换后内容的起始位置,替换后容节选长度)
例一:
1 | string str = "id=001;"; |
那么打印str之后的内容就会是id=003
例二:
1 | string str = "abcde;"; |
那么打印str之后的内容就会是abc******
;
例三:
1 | string str = "id=001;"; |
str为id=zhangsan;
例四:
1 | string str = "id=001;"; |
str为id=san;
其实后面几个用的也不多
.erase
能替换,也能删除.erase(删除的起始位置)
.erase(删除起始位置,删除的长度)
1 | string str = "id=001;" |
str显示为id=
1 | string str = "id=001;" |
str显示为id=
clear
顾名思义就是清除,对应的就是清空字符串的内容。
就不演示了,反正使用了之后在打印字符串就是空的
练习
string str = "id=xxx;name=xxx;sex=x;phone=xxxxxxx;";
假设有这么一句字符串,需要你实现输入选项如id,拆解出id=后面的参数,不含;
1 | int main(){ |
结语
内置的方法还是香的,自己能造出轮子也不失为一种办法。