SLT(标准模板库)的六大组件
STL的缺点
编码
C++文档
String
1、char和wchar_t
#include <string>
int main()
{
cout << sizeof(char) << endl;
cout << sizeof(wchar_t) << endl;
}
2、String构造
#include<string.h>
int main()
{
string s1;
string s2("hello world");
string s3("陕西");
string s4(10, 'a');
string s5(s2);
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
cout << s5 << endl;
s1 = s5;
cout << s1 << endl;
return 0;
}
3、插入字符串
#include<string.h>
int main()
{
string s1("hello");
s1.push_back('+');//尾插一个字符
s1.append("world");//插入一个字符串
cout << s1 << endl;
// 尾插更推荐用+=;
s1 += '!';
s1 += "hello 来了";
cout << s1 << endl;
return 0;
}
4、字符串和数字来回转换
void test_string7()
{
int i = 12334;
//转成字符串
string str = to_string(i);
cout << str << endl;
//转成整数
int j = stoi(str);
}
int main()
{
test_string7();
return 0;
}
遍历每个字符–重点
下面的test都需要这个
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;
template<class T>
class basic_string
{
public:
char& operator[] (size_t pos); // 读 写
//operator[]内核是这样检查越界的
//{
//assert(pos < _size);
//return _a[pos];
//}
//C语言strcpy的时候用到
const char* c_str() const
{
return _a;
}
const char& operator[] (size_t pos) const; // 读
private:
T* _a;
size_t _size;
size_t _capacity;
};
- 方法1:数组
- 方法2:auto
- 方法3:迭代器
void test_string1()
{
string s1;
string s2("hello");
cout << s2 << endl;
//1、 遍历 修改+读取--数组
for (size_t i = 0; i < s2.size(); ++i)
{
s2[i] += 1;
}
for (size_t i = 0; i < s2.size(); ++i)
{
cout << s2[i] << " ";
}
//s2[20];不能越界--err
cout << endl;
//2、 遍历 修改+读取--auto(本质是迭代器)
for (auto& ch : s2)//char代替auto也行, 要修改所以加引用
{
ch -= 1;
}
cout << endl;
for (auto ch : s2)
{
cout << ch << " ";
}
cout << endl;
//3、 遍历 修改+读取--迭代器
string::iterator it = s2.begin();
while (it != s2.end())
{
*it += 1;
++it;
}
it = s2.begin();
while (it != s2.end())
{
cout << *it << " ";
++it;
}
cout << endl;
// 迭代器的好处,可以用统一类似的方式去访问修改容器
vector<int> v = { 1, 2, 3, 4 };
vector<int>::iterator vit = v.begin();
while (vit != v.end())
{
cout << *vit << " ";
++vit;
}
cout << endl;
list<int> lt = { 1, 2, 3, 4 };
list<int>::iterator lit = lt.begin();
while (lit != lt.end())
{
cout << *lit << " ";
++lit;
}
cout << endl;
}
int main()
{
test_string1();
}
迭代器–重点
1、const迭代器
void Print(const string& s)//const对象只能读不能写,用const迭代器
{
string::const_iterator it = s.begin();//const迭代器
while (it != s.end())
{
//*it += 1;不能给常量*it赋值--err
cout << *it << " ";
++it;
}
cout << endl;
}
void test_string2()
{
string s1("hello");
Print(s1);
}
int main()
{
test_string2();
}
2、反向迭代器
void test_string2()
{
string s1("hello");
反着遍历对象--可读可写
string::reverse_iterator rit = s1.rbegin();
while (rit != s1.rend())
{
//*rit += 1;
cout << *rit << " ";
++rit;
}
cout << endl;
}
int main()
{
test_string2();
}
3、反向迭代器和const
void Print(const string& s)//const对象只能读不能写,用const迭代器
{
//string::const_reverse_iterator rit = s.rbegin();
auto rit = s.rbegin();
while (rit != s.rend())
{
//*rit += 1;--err
cout << *rit << " ";
++rit;
}
cout << endl;
}
void test_string2()
{
string s1("hello");
Print(s1);
}
int main()
{
test_string2();
}
size、length、capacity
void test_string3()
{
string s1("hello");
//推荐用size
cout << s1.size() << endl;
cout << s1.length() << endl;
cout << s1.capacity() << endl;
//resize是改变长度的
string s3("hello world");
cout << s3 << endl;
cout << s3.size() << endl;//11个字符
//s3[19] = 'y';--err,operator[]会检查越界
//增长
//s3.resize(20, 'x');//用这个不用下面那个的话,看不到的\0可以看到都变为x
s3.resize(20);
s3[19] = 'y';//第19个字符为y
cout << s3 << endl;
cout << s3.size() << endl;//20个字符,11后面都是\0
//减短
string s4("hello world");
s4.resize(5);
cout << s4 << endl;
cout << s4.size() << endl;
//reserve--改变capacity
//增容--增容的倍数和平台有关
string s5("hello world");
s5.reserve(25);//增容的倍数和平台有关与这里数字无关
cout << s5 << endl;
cout << s5.size() << endl;
cout << s5.capacity() << endl;
//缩容--是否缩小和平台有关
s5.reserve(10);
cout << s5 << endl;
cout << s5.size() << endl;
cout << s5.capacity() << endl;
}
int main()
{
test_string3();
}
append 、+=、erase
void test_string5()
{
string s1("hello");
string s2("world");
// 常用的
s1 += ' ';
s1 += s2;
s1 += "!!!";
cout << s1 << endl;
// 能不用就不要用,因为insert和erase在头部或者中间等位置插入删除
// 需要挪动数据,效率低下,尽量少用。了解即可
s1.insert(0, "bit ");
cout << s1 << endl;
cout << "------------------------------------" << endl;
string s3("hello world");
cout << s3 << endl;
//从第五个数据后面开始删两个
s3.erase(5, 2);
cout << s3 << endl;
//从第五个数据后面开始删两个
s3.erase(5, 20);
cout << s3 << endl;
//从第五个数据后面开始删完
s3.erase(5);
cout << s3 << endl;
}
find、rfind–微重点
void test_string6()
{
// 取出文件的后缀
string file1("test.txt.zip");
string file2("test.c");
size_t pos1 = file1.rfind('.');//用find不用rfind则file1的后缀会输出为.txt.zip
if (pos1 != string::npos)
{
//string sub1 = file1.substr(pos1, file1.size()-pos1);
string sub1 = file1.substr(pos1);//从pos1位置开始取
cout << sub1 << endl;
}
size_t pos2 = file2.rfind('.');
if (pos2 != string::npos)
{
string sub2 = file2.substr(pos2);
cout << sub2 << endl;
}
// 取出url中协议--https、 域名--www.cplusplus.com、 uri--reference/string/string/find/
string url("https://www.cplusplus.com/reference/string/string/find/");
cout << url << endl;
//协议
size_t i1 = url.find("://");//从0开始搜索
if (i1 != string::npos)
{
string protocol = url.substr(0, i1 - 0);
cout << "protocol:" << protocol << endl;
}
//域名
size_t i2 = url.find('/', i1 + 3);//从i1+3即w开始搜索找/
if (i2 != string::npos)
{
string domain = url.substr(i1 + 3, i2 - (i1 + 3));//i2 - (i1 + 3找的域名的长度
cout << "domain:" << domain << endl;
}
//uri
string uri = url.substr(i2);
cout << "uri:" << uri << endl;
}
int main()
{
test_string6();
return 0;
}