目录
- 一、string的定义方式
- 二、 string类对象的容量操作
- 三、string类对象的访问及遍历操作
- 四、string类对象的修改操作
- 五、string类非成员函数
一、string的定义方式
string是个管理字符数组的类,其实就是字符数组的顺序表。
它的接口也是非常多的。本章介绍一些常见使用如文档
string类实现了多个构造函数的重载,常用的构造函数如下
```
default (1) string(); //无参构造copy (2) string (const string& str); //拷贝str所指的字符序列substring (3) string(const char* string& str, size_t pos,size_t len =npos); //拷贝str字符串的第pos到最后一个字符from c-string (4) string (const char* s); //用C-string来构造string类对象,有'\0'string(const string& s); //拷贝构造from sequence (5) string (const char* s, size_t n); //拷贝s字符串的前n个进行初始化fill (6) string (size_t n, char c); //string类对象中包含n个字符c```
使用示例
//常用
string s1; //无参构造
string s2("羚羊"); //带参构造
string s3("this is a little sheep"); //带参构造
string s4(s2); //拷贝构造//了解
string s5(7, '#'); //生成7个'#'字符的字符串
string s6(s3, 0, 3); //从s3字符串第0下标拷贝3个字符
string s7(s3, 9); //从s3字符串第8下标拷贝到结尾
二、 string类对象的容量操作
函数名称 | 功能 |
---|---|
size(重点) | 返回字符串有效字符长度 |
length | 返回字符串有效字符长度 |
capacity | 返回空间总大小 |
max_capacity | 返回最大空间 |
empty (重点) | 检测字符串释放为空串,是返回true,否则返回false |
clear (重点) | 清空有效字符 |
reserve (重点) | 为字符串预留空间** |
resize (重点) | 将有效字符的个数该成n个,多出的空间用字符c填充 |
int main()
{string s1("hello world");//在string类里等价,常用sizecout << s1.size() << endl;cout << s1.length() << endl;//根据编译器的不同结果也不同cout << s1.max_size() << endl; cout << s1.capacity() << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;s1.clear();cout << s1.size() << endl; //只清理字符数据cout << s1.capacity() << endl; //不清理空间string s2("hello c++");//开空间,知道一共需要多少空间一次性开好空间后续就不需要扩容了//缩容是重新拷贝一块空间把数据拷贝进去,释放掉原空间s2.reserve(100);cout << s2.size() << endl;cout << s2.capacity() << endl;//开空间+初始化默认\0s2.resize(100, 'x'); //也可选定初始化字符cout << s2.size() << endl;cout << s2.capacity() << endl;s2.resize(20); //如果只要前20个,把后面数据清掉cout << s2.size() << endl;cout << s2.capacity() << endl;//empty是string的判空函数,我们可以调用strcmp函数来实现,strcmp函数是用于比较两个字符串大小的函数,当两个字符串相等时返回0。bool empty(){return strcmp(_str, "") == 0;}return 0;
}
三、string类对象的访问及遍历操作
迭代器在任何容器中都是相通的,虽然各个容器结构不一样,但在用法上都是通用的。
iterator是像指针一样的类型,iterator提供了一种统一的方式访问和修改容器的数据,算法就可以通过迭代器去处理容器中数据。
//正向迭代器
iterator
const iterator
//反向迭代器
reverse_iterator
const_reverse_iterator
函数名称 | 功能 |
---|---|
operator[] (重点) | 返回pos位置的字符,const string类对象调用 |
begin+ end | begin获取第一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器 |
rbegin + rend | rbegin获取最后一个有效字 符的迭代器 + rend获取第一个字符下一个位置的迭代器 |
范围for | C++11支持更简洁的范围for的新遍历方式 |
#include<iostream>
#include<string>
using namespace std;int main()
{//[]运算符重载(可读可写)//[ ]运算符的重载是为了让string对象能像C字符串一样,通过[ ] +下标的方式获取字符串对应位置的字符char& operator[](size_t i) //只读const char& operator[](size_t i)const{assert(i < _size); //检测下标的合法性return _str[i]; //返回对应字符}string s;string s1("hello world");cout << s1 << endl; //普通直接打印//1. 下标+[]遍历,可对字符之间做控制和修改for (int i = 0; i < s1.size(); i++){s1[5] = '-'; //下标5的位置改为-cout << s1[i] << ' ';}cout << endl;//2.迭代器string::iterator it = s1.begin();while (it != s1.end()){cout << *it++ << ' ';}cout << endl;//3.范围for,其实底层就是迭代器for (auto ch : s1){cout << ch << ' ';}cout << endl;//逆置数组string s2("hello world");//写法等价auto rit = s2.rbegin(); //auto可自动识别类型string::reverse_iterator rit = s2.rbegin();while (rit != s2.rend()){cout << *rit++ << " ";}return 0;
}
四、string类对象的修改操作
函数名称 | 功能 |
---|---|
push_back | 在字符串后尾插字符c |
insert | 插入字符或字符串 |
append | 在字符串后追加一个字符串 |
assign | 覆盖写入字符串 |
erase | 删除字符 |
operator= | 重载后该运算符支持string类的赋值、字符串的赋值以及字符的赋值 |
operator+= (重点) | 在字符串后追加字符串str |
c_str | 返回C格式字符串 |
find + npos | 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置 |
rfind | 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置 |
substr | 在str中从pos位置开始,截取n个字符,然后将其返回 |
+=运算符的重载是为了实现字符串与字符、字符串与字符串之间能够直接使用+=运算符进行尾插。
+=运算符实现字符串与字符之间的尾插直接调用push_back函数即可。
1、使用push_back进行尾插
int main()
{string s1("hello");s1.push_back(' '); //插入字符s1.push_back('c');s1.push_back('p');s1.push_back('p');cout << s1 << endl; //hello cppreturn 0;
}
2、使用insert、append、assign插入
int main()
{string s1("hello world");//追加s1.append("abcde");cout << s1 << endl; //hello worldabcdes1.assign("1234567");cout << s1 << endl; //覆盖如上内容改为1234567//string& insert (size_t pos, const string& str);s1.insert(0, "hello"); //第0位置插入hellos1.insert(5, "world"); //第5位置插入worldcout << s1 << endl; //helloworld1234567//string& insert (size_t pos, size_t n, char c);s1.insert(0, 7, 'x'); //第0字符插入7个x字符cout << s1 << endl; //xxxxxxxhelloworld1234567//void insert (iterator p, size_t n, char c);s1.insert(s1.begin()+7, 7, 'y'); //第7个位置插入7个x字符cout << s1 << endl; //xxxxxxxyyyyyyyhelloworld1234567
}
3.使用erase删除
int main()
{string s1("hello world");s1.erase(5, 1); //下标第5个位置删除一个字符cout << s1 << endl;s1.erase(5); //下标5之后都删除string s2("hello world");//两个写法头删s2.erase(0, 1);s2.erase(s2.begin());
}
4.截取网站每个部分
int main()
{string url = "https://cplusplus.com/reference/string/string/?kw=string";size_t pos1 = url.find("://");string protocaol;if (pos1 != string::npos){protocaol = url.substr(0, pos1);}cout << protocaol << endl;string domain;string uri;size_t pos2 = url.find('/',pos1+3);if (pos2 != string::npos){domain = url.substr(pos1 + 3, pos2 - (pos1 + 3));uri = url.substr(pos2 + 1);}cout << domain << endl;cout << uri << endl;
}
5.+和+=
int main()
{string s1;string s2("hello");//支持string类的赋值s1 = s2;cout << s1 << endl; //hello//支持字符串的赋值s1 = "world";cout << s1 << endl; //world//支持字符的赋值s1 = 'x';cout << s1 << endl; //xstring s3;string s4("hello");//支持string类的复合赋值s3 += s4;cout << s1 << endl; //hello//支持字符串的复合赋值s3 += " world";cout << s3 << endl; //hello world//支持字符的复合赋值s3 += '!';cout << s4 << endl; //hello world!return 0;
}
五、string类非成员函数
operator+ | 尽量少用,因为传值返回,导致深拷贝效率低 |
---|---|
operator>> (重点) | 输入运算符重载 |
operator<< (重点) | 输出运算符重载 |
getline (重点) | 获取一行字符串 |
relational operators (重点) | 大小比较 |
1.string类中也对>>和<<运算符进行了重载,这就是为什么我们可以直接使用>>和<<对string类进行输入和输出的原因。
istream& operator>> (istream& is, string& str);
ostream& operator<< (ostream& os, const string& str);
int main()
{string s;cin >> s; //输入cout << s << endl; //输出return 0;
}
2.string类中还对一系列关系运算符进行了重载,它们分别是==、!=、<、<=、>、>=。重载后的关系运算符支持string类和string类之间的关系比较、string类和字符串之间的关系比较、字符串和string类之间的关系比较。
int main()
{string s1("abcd");string s2("abde");cout << (s1 > s2) << endl; //0cout << (s1 < s2) << endl; //1cout << (s1 == s2) << endl; //0return 0;
}
这些重载的关系比较运算符所比较的都是对应字符的ASCII码值。
3.使用>>进行输入操作时,当>>读取到空格便会停止读取,我们将不能用>>将一串含有空格的字符串读入到string对象中。
用法1
可以用getline函数完成一串含有空格的字符串的读取操作。
istream& getline (istream& is, string& str);
getline函数将从is中提取到的字符存储到str中,直到读取到换行符’\n’为止。
int main()
{string s;getline(cin, s); //输入:hello worldcout << s << endl; //输出:hello worldreturn 0;
}
用法2
istream& getline (istream& is, string& str, char delim);
getline函数将从is中提取到的字符存储到str中,直到读取到分隔符delim或换行符’\n’为止。
int main()
{string s;getline(cin, s, 'l'); //输入:hello worldcout << s << endl; //输出:hello worreturn 0;
}