C++ string类(前)
目录
一、前言
二、正文
1.1什么是string类
1.2为什么学习string类
1.3string使用注意
1.4 string 类常用接口说明
1.4.1string类对象的常见构造
1.4.2string类对象的容量操作
1.4.3 string 类对象的访问以及遍历操作
1.4.4 string 类对象的修改操作
三、结言
一、前言
大家好,上次我们已经了解到了C++中重要组成部分——模板,今天我们讲讲标准库中的——string类。
二、正文
1.1什么是string类
以上是我在cplusplus网站上截图下来的,并配上译文的图片(译文仅限参考)
有兴趣的小伙伴,可以自发到该网站上查看https://legacy.cplusplus.com/reference/string/string/?kw=string
1.2为什么学习string类
C语言中,字符串是以 '\0' 结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OPP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
1.3string使用注意
在使用string类时,必须包含#include头文件以及using namespace std;
1.4 string 类常用接口说明
1.4.1string类对象的常见构造
1.4.2string类对象的容量操作
注意:
- size ()与length ()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一股情况下基本都是用size()。
- clear()只是将string中有效字符清空,不改变底层空间大小。
- resize(size_t n) 与resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
- reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
1.4.3 string 类对象的访问以及遍历操作
#include<iostream> using namespace std; int main() { string s1("hello world"); //1、operator[ ]遍历 cout << s1[0] << s1[1] << endl;//输出:he [ ]被重定义过了,适用于字符串。类似于数组访问 //遍历操作如下: int i = 0; while (i<s1.size()) { cout << s1[i++]<<" ";//这里会打印出hello world } cout << endl; //2、begin+end遍历 //这里面的迭代器(iterator)类似我们之前所学的指针 string::iterator s2=s1.begin();//s1.begin()会获取字符串中得第一个字符,这里是h cout <<* s2 << endl;//输出:h string::iterator s3 = s1.end();//s1.end()实际是有效字符串的最后一个字符的下一个位置,即这里的d后面的'\0' cout << *(s3-1) << endl;//输出d //遍历操作如下: while (s2 != s3) { cout << *s2++ << " ";//这里会打印hello world } cout << endl; //3、rbegin+end遍历 //rbegin+rend就相当于是begin+end的反转版,从最后一个字符向前打印。 string::reverse_iterator s4 = s1.rbegin();//s1.begin()相当于获取的是字符串“hello world”的最后一个字符'd' cout << *s4 << endl;//输出:d string::reverse_iterator s5 = s1.rend();//s1.rend()相当于获取的是字符串“hello world”的第一个字符'h'的下一个字符'\0' cout << *(s5-1)<< endl;//输出:h //遍历操作如下: while(s4!=s5) { cout << *s4++ << " ";//这里会打印dlrow olleh } cout << endl; //4、范围for遍历 //s可以直接在范围for中定义,用于范围for中遍历 //此外我们可以不用对s多余的操作,s自动会遍历完整个字符串 //值得注意的是:范围for只适用于存放于数组类的字符串结构 //一旦字符串存放于类似树这样的结构,我们就不能使用范围for遍历 for (char s : s1)//其中char是数据s的类型,可以是int、double、char类型等,即范围for遍历不仅适用于字符串,同样适用于其他类型数据 { cout << s << " ";//输出hello world } cout << endl; return 0; }
1.4.4 string 类对象的修改操作
#include<iostream> using namespace std; int main( ) { //string类对象的修改操作 string s11("hello world"); //1、puhs_back(在字符串后尾插字符) s11.push_back('a'); cout << s11 << endl;//输出:hello worlda //2、append(在字符串后追加一个字符串) s11.append("bb"); cout << s11 << endl;//输出:hello worldabb //3、operator+=(在字符串后面追加字符串) string s12 = s11 + "cc"; cout << s12 << endl;//输出:hello worldabbcc //4、c_str(返回C语言格式的字符串) const char* c; c = s12.c_str(); cout << c << endl;//输出:hello worldabbcc //5、find+npos(从字符串pos位置开始往后找字符,返回该字符在字符串中的位置) string s14("hello world"); // 这里我们从下标0的位置开始往后面找字符'o' cout << s14.find('o', 0) << endl;//输出:4 说明字符o从下标0开始找在下标4的位置 cout << s14.find('o', 5) << endl;//输出:7 //值得注意的是:从下标几开始找这个形参是重要的,因为从下标5开始找的话,就找不到字符串”hello world“ //中的第一个'o'而是会返回第二个1字符'o'在字符串中的位置——7 cout << s14.find('s', 0) << endl;;//如果你在一个字符串中找一个根本没有的字符,将输出随机数字 //6、rfind(从字符串pos位置开始往前找字符,返回该字符在字符串中的位置) //rfind和find类似 string s15("hello world"); cout << s15.rfind('o', 5) << endl;//输出:4 cout << s15.rfind('o', 3) << endl;//和find一样输出一串数字:18446744073709551615、 //7、substr(在str中从pos位置开始,截取n个字符,然后将其返回) string s16 = s15.substr(3, 8); cout << s16 << endl;//输出:lo world 这里我们从字符串”hello world“下标3位置'l'开始截取后面8个字符,正好可以将'l'后面的字符打印完 string s17 = s15.substr(3, 30);//即使截取后面的长度n,远远长过原字符串,编译器也不会报错 cout << s17 << endl;//输出:lo world return 0; }
注意:
- 在string尾部追加字符时,s.push(c) / s.append(1,c) / s+='c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=不仅可以连接单个字符,还可以连接字符串。
- 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
三、结言
今天的分享就到这了,我们下期再见