您现在的位置是:首页 >技术交流 >【C++】string的使用网站首页技术交流
【C++】string的使用
前言
?从这里开始,便开始介绍 string 和 STL 容器的使用,以及相关容器的模拟实现,欢迎和博主一起学习。
目录
引入
?相信在使用C语言的时候,表示字符串的方式过于麻烦,一直是长期困扰我们的问题之一。
?通常我们会使用一个固定大小的字符数组,进行存储。
?若之后我们需要将其更改成更长的字符串,原来的数组便无法满足需求,需要重新申请。
?因此,C语言的字符数组无法很好地满足修改的要求,于是在 C++ 中引入叫作 string 一个类。 ---属于头文件<string>。
?而 string 又是由 basic_string 这个模板类而来,根据模板参数的不同还延申了其他的 string。
之所以有这么多的容器,是由于在给不同国家的语言进行编码时,每个国家文字的数量不尽相同,如 ASCII 码中128位就绰绰有余了。换是中文或者其他国家的语言,就无法适配。因此发明了 unicode (统一码、万国码),进行编码。同时衍生了几个不同的版本,比如UTF 8就是8个比特位,就是一字节的大小对语言进行编码,同时兼容了 ASCII 码。还有 UTF 16 和 UTF 32 分别是使用了 2 字节和 4 字节进行编码。感兴趣的可以自行了解,这里不再赘述。
?因此这里的 u16string、u32string 和 wstring 与普通 string 的区别都是内置类型不同而已。
?而大部分的时间我们都是使用普通 string 的,这次也主要介绍 string 的使用,同时还会讲讲头文件中的一些实用性的函数。
构造与赋值重载
构造
?string 的接口确实是非常多,也不需要每个都记住,大致了解一下就行。
?比如第一个就是无参实例化一个 string ,即它的默认构造函数。
int main()
{
string s;
return 0;
}
?第四个则是用一个字符串来初始化 string。
int main()
{
string s("hello world");
return 0;
}
?同时也可以这样写,实际上是发生了类型转换,不清楚的可以看看这篇文章【C++】类与对象(下)
int main()
{
string s = "hello world";
return 0;
}
?第二个构造函数则是拷贝构造,用已有的 string 类型进行初始化。
int main()
{
string s1 = "hello world";
string s2(s1);
return 0;
}
?至于第三第五个都是在原有的基础上对读取长度的限制,达到以部分内容进行初始化的效果。
?在函数中还提到了一个缺省值为 npos,这个值是 string 类里面自己定义的一个值。虽然上面值写的是 -1 ,但是它的值并不是 -1 ,因为它是一个无符号整数,因此其表示的其实是无符号整数的最大值。
?若你想在 string 中塞入一定数量的某个字符,则可以使用第六个构造函数。
?第七个函数则是使用迭代器区间进行初始化,这个我们放到迭代器的部分再讲。
赋值重载
?在内部还有对赋值运算符进行重载,可以对已经实例化的 string 类型进行赋值。
容量操作
容量查询
?其实说多了,string 就像我们以前学的顺序表,只不过 string 是专门用来存字符的而已。
?因此,还是需要一个值表示已存数量、一个值表示容量。
其中 size 就代表当前字符的数量,capacity 则表示当前 string 的容量。类内部也提供了接口供我们访问。
?直接调用类中的函数即可。
?其实还有一个叫 length 的接口,本质上作用跟 size 是一样的,因为要跟 STL 靠齐,所以新增加了 size 的接口。
int main()
{
string s = "hello";
cout << s.size() << endl; //内容数量
cout << s.length() << endl;
cout << s.capacity() << endl; //容量
return 0;
}
容量修改
?库中提供两个接口供我们进行容量的修改,分别是 reserve 和 resize。
reserve
?使用 reserve 能够更改 string 的 capacity,不改变size。若我们提前知道需要使用的大小,可以提前扩大 string 的容量,避免重新开辟空间而引发拷贝所带来的消耗。并且 reserve 只能扩容而无法更改字符串内容,即不能缩容。
resize
?使用 resize 不仅可以更改 capacity 还可以修改 size,扩容时还可以再输入一个 char 作为扩容时初始化的值,否则缺省为 。
?若输入的值 n 小于 string 当前的 size,当前的 size 就变为n,即删除第n个字符之后的字符。
?缩小时只更改 size 而不修改 capacity,这是由于,内存管理中并不支持原地缩容,否则会增加内存管理的难度。因此缩容都是开一块新的空间,再将数据拷贝进去,浪费了大量的时间,所以不会轻易缩容。
清空判空
?还有 clear 用于清空字符串,empty 用于判空,在合适时机会使用即可。
迭代器
正向迭代器
?要说 C++ 的容器与 C 语言自己写的数据结构差别最大的一件事,无非就是C++的库中还有迭代器。
?对初学者而言,可以将其粗略地理解成指针。我们可以通过 begin 拿到字符串的第一位,end 拿到最后一个元素的下一位。
?由此便可以实现对 string 的遍历。
反向迭代器
?不仅有正向迭代器还有反向迭代器,使用 rbegin 和 rend 获得反向迭代器可以反向迭代。
?值得注意的是,无论是正向迭代器还是反向迭代器,迭代的时候都是++。
const迭代器
?对与 const string 类型的也有 const 的迭代器,使用这个迭代器后只能访问,不能写入。
?因此上面用迭代器区间构造函数参数,现在我们便能看懂了,就是限定一个范围,进行初始化。
成员访问
下标访问
?string 中对[ ]进行了重载,因此可以使用 [ ] 直接进行下标的访问。
?同时 at 函数也支持下标访问。
?二者之间的区别只有 [ ] 越界会直接报错,而 at 越界则会抛异常。
边界访问
?可以使用 front 和 back 函数访问第一个字符和最后一个字符。
但是这两个函数不能被空的 string 调用!!
增删查改
插入
push_back
?这个函数我们以前也经常写,用于在 string 的结尾插入一个字符。
append
?与 push_back 不同,append 往 string 结尾插入可以是多种多样的。
int main()
{
string s = "hello world";
string s1 = "cba";
s.append(" abc "); //插入字符串
cout << s << endl;
s.append(s1); //插入string
cout << s << endl;
s.append(3, '!'); //插入3个!
cout << s << endl;
return 0;
}
+=
?其实上面的 push_back 和 append 都可以用 += 代替,既可以插入字符也可以插入字符串和 string。只不过没有限定插入长度而已。
int main()
{
string s = "hello world";
string s1 = "cba";
s += " abc ";
cout << s << endl;
s += s1;
cout << s << endl;
s += '!';
cout << s << endl;
return 0;
}
?也并没有说一定那个函数比较好,还是看自己怎么喜欢怎么来。
insert
?前面三个函数都是在 string 的末尾进行插入,而 insert 可以在 string 的任意位置进行字符、字符串和 string 的插入。
?虽然看起来很方便,但是 string 本质上还是顺序表,使用 insert 还是伴随着数据的挪动,因此不推荐经常使用。
删除
?删除就没有插入那么花里胡哨了,只有 erase 这个函数,指定位置删除即可。
查找
find
?通过find我们可以查找 string 中出现的第一个字符、字符串和 string,找到了就返回匹配的第一个字符的下标,找不到返回 npos。
rfind
?rfind 与 find 相反,rfind 是从 string 的末尾开始找第一个匹配的字符或字符串,并返回其下标。
交换
?我们都知道,库里面就有一个 swap 函数了,那么为什么在 string 之中还要再写一个 swap 函数呢?
?这是由于库中的 swap 函数是这直接拷贝一个中间值进行交换,实际上 string 中的交换并不需要这么麻烦,只需要交换类中的指针和其他基础数据即可。
?因此库中的 swap 避免了多次拷贝带来的无端的消耗,交换的效率更高。
其他操作
输入输出
?不仅如此,string 还有对流输入和流提取进行重载,这样我们就能直接使用 cin cout 对 string 进行输入和输出了。
getline
?在使用 cin 输入时,空格和换行都会被 cin 当作是分隔符,若我们想只以换行作为识别的标志,则需要使用 getline。
string转整型
?在 string 这个库中还有一些实用的函数,这里我们讲讲 stoi 作为例子。
?该函数可以将一个 string 转换成 int 类型的整数。正常使用的话,都有缺省值,直接传 string 类型的参数进去就行了。
整型转string
?既然有了 string 转整数,自然也有整数转 string 了。 只要把值传进去,就会返回一个 string。但是也不仅仅局限于整型,浮点型、无符号整型也是可以的。
?好了,今天string的使用讲解到这里就结束了,如果这篇文章对你有用的话还请留下你的三连加关注