目录
一.string类
二.string类常用接口
0.静态成员变量npos
1.构造函数
2.赋值运算符重载
3.逐个字符遍历:[]重载与at
?3.0.范围for
4.迭代器(正向/反向/正向常量/反向常量迭代器)
5.追加字符/字符串:push_back、append、operator+=
6.capacity(容量,不包括\0所占空间),max_size,reserve,resize
7.assign赋值,insert插入,erase删除,replace替换
8.c_str,给C库提供的接口
9.find、rfind、substr
10.?find_first_of、find_last_of、find_first_not_of、find_last_not_of
前言:什么是STL?
STL(standard template libaray)意为标准模板库,是C++标准库的重要组成部分
不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架
一.string类
string类是basic_string类模板使用char实例化的一个模板类,专门用来处理字符/字符串类型,但注意,不能操作多字符或者变长字符的序列,使用时必须包含<string>
二.string类常用接口
0.静态成员变量npos
static const size_t npos = -1;
npos是无符号整型,定义为-1,也就是无符号整形的最大值4294967295,使用时加上类域?string::npos
1.构造函数
void test_string1()
{
//1.string();
cout << "1." << endl;
string s1;
cout << s1 << endl;
//2.string(const char* s)
cout << "2." << endl;
string s2("hello world!!!");
cout << s2 << endl;
//3.string(const string& str)
cout << "3." << endl;
string s3(s2);
cout << s3 << endl;
//4.string(const string& str, size_t pos, size_t len = npos)
cout << "4." << endl;
string s4(s3, 6, 4);
cout << s4 << endl;
string s5(s3, 6, 20);
cout << s5 << endl;
string s6(s3, 6);
cout << s6 << endl;
//5.string(const char* s, size_t n);
cout << "5." << endl;
string s7("hello world", 4);
cout << s7 << endl;
//6.string(size_t n, char c)
cout << "6." << endl;
string s8(5, 'm');
cout << s8 << endl;
//7.迭代器版本
cout << "7." << endl;
string s9("helloooooo");
string s10(s9.begin(), s9.end() - 5);
cout << s10 << endl;
}
2.赋值运算符重载
void test_string2()
{
//1.string& operator=(const string& str)
cout << "1." << endl;
string s1("hello world!");
string s2("hello string!");
s1 = s2;
cout << s1 << endl;
//2.string& operator=(const char* s)
cout << "2." << endl;
string s3("ni hao");
s3 = "hello";
cout << s3 << endl;
//3.string& operator=(char c)
cout << "3." << endl;
string s4("hhhhhh");
s4 = 'h';
cout << s4 << endl;
}
3.逐个字符遍历:[]重载与at
void test_string3()
{
//char& operator[](size_t pos)
cout << "1." << endl;
string s1("helloworld!");
for (size_t i = 0; i < s1.size(); i++)
{
cout << s1[i] << " ";
}
cout << endl;
//const char& operator[](size_t pos)
cout << "2." << endl;
const string s2("helloworld!");
for (size_t i = 0; i < s2.size(); i++)
{
cout << s2[i] << " ";
}
cout << endl;
//char& at(size_t pos)
cout << "3." << endl;
const string s3("helloat");
for (size_t i = 0; i < s3.size(); i++)
{
cout << s3.at(i) << " ";
}
cout << endl;
//const char& at(size_t pos) const
cout << "4." << endl;
const string s4("helloat");
for (size_t i = 0; i < s4.size(); i++)
{
cout << s4.at(i) << " ";
}
cout << endl;
}
?3.0.范围for
void test_for()
{
string s("hello world!!");
for (auto ch : s)
{
cout << ch << " ";
}
cout << endl;
}
?范围for遍历的底层实际就是迭代器,可以从汇编角度观察到
4.迭代器(正向/反向/正向常量/反向常量迭代器)
void test_string4()
{
//正向迭代器 - iterator
//[s.begin(),s.end()) - 左闭右开
cout << "1." << endl;
string s1("hello iterator");
string::iterator it = s1.begin();
while (it != s1.end())
{
cout << *it << " ";
it++;
}
cout << endl;
//反向迭代器 - reverse_iterator
//(s.rend(),s.rbegin()] - 左开右闭
cout << "2." << endl;
string s2("hello reverse_iterator");
string::reverse_iterator rit = s2.rbegin();
while (rit != s2.rend())
{
//正/反向迭代器可以通过it修改内容
*rit = 'x';
cout << *rit << " ";
rit++;
}
cout << endl;
cout << s2 << endl;
//常量迭代器 - const_iterator
cout << "3." << endl;
const string s3("hello const_iterator");
//auto cit = s3.begin();自动推导 begin返回什么auto就是什么
string::const_iterator cit = s3.begin();
while (cit != s3.end())
{
cout << *cit << " ";
cit++;
}
cout << endl;
//反向常量迭代器 - const_reverse_iterator
cout << "4." << endl;
const string s4("hello const_reverse_iterator");
string::const_reverse_iterator crit = s4.rbegin();
while (crit != s4.rend())
{
cout << *crit << " ";
crit++;
}
cout << endl;
}
5.追加字符/字符串:push_back、append、operator+=
void test_string5()
{
cout << "1." << endl;
string s1("hello push_back");
s1.push_back('a');
cout << s1 << endl;
cout << "2." << endl;
string s2("hello append");
s2.append("aaaaa");
cout << s2 << endl;
cout << "3." << endl;
string s3("hello operator+=");
s3 += "hehe";
s3 += 'a';
cout << s3 << endl;
cout << "4." << endl;
string s4("hello");
s4.append(s3.begin(), s3.end() - 5);
cout << s4 << endl;
}
6.capacity(容量,不包括\0所占空间),max_size,reserve,resize
void test_string7()
{
cout << "1." << endl;
string s1("hello");
cout << s1.max_size() << endl;
cout << s1.capacity() << endl;
//查看vs下的扩容机制
cout << "查看vs下的扩容机制:" << endl;
size_t sz = s1.capacity();
for (size_t i = 0; i < 100; i++)
{
s1.push_back('a');
if (sz != s1.capacity())
{
sz = s1.capacity();
cout << "capacity:" << sz << endl;
}
}
cout << "2." << endl;
string s2("aaaaaaaaaaaaaaaaa");
cout << "reserve之前capacity:" << s2.capacity() << endl;
s2.reserve(1000);//开空间
cout << "reserve之后capacity:" << s2.capacity() << endl;
s2.resize(1000,'x');//开空间+初始化
cout << "resize之后capacity:" << s2.capacity() << endl;
}
注意:空间只可扩容不可缩小,reverse或者resize开出去的空间多大就是多大,例如第一次reverse(1000)第二次reverse(500)由于第二次比第一次小,空间就按照第一次来算?
7.assign赋值,insert插入,erase删除,replace替换
void test_string8()
{
cout << "1." << endl;
string s1;
s1.assign("hehe");
cout << s1 << endl;
cout << "2." << endl;
string s2("hello insert");
s2.insert(1, " OH! ");//在pos为1的位置后插入字符串
cout << s2 << endl;
//iterator insert (const_iterator p, char c);
s2.insert(s2.begin(), 'K');
cout << s2 << endl;
s2.erase(0, 1);//在0位置向后删除1个字符
s2.erase(s2.begin() + 2);
cout << s2 << endl;
cout << "3." << endl;
string s3("helloworld");
string s4("zsl");
s3.replace(0, 5, s4);//将0~5替换成s4
cout << s3 << endl;
}
注意:尽量少使用插入,删除,替换这些接口,因为底层实现是要大量挪动数据的,时间复杂度较高?
8.c_str,给C库提供的接口
void test_string9()
{
string s1("string.cpp");
FILE* p = fopen(s1.c_str(), "r");
assert(p);
char ch = 0;
while (ch != EOF)
{
ch = fgetc(p);
cout << ch;
}
cout << endl;
s1 += '\0';
s1 += "hehehe";
cout << s1 << endl;//以size为结束标准
cout << s1.c_str() << endl;//以'\0'为结束标准
}
许多软件的底层使用C语言实现,因为C++兼容C,使用C实现接口,C、C++都可以使用。
例如:fopen是C语言标准库提供的接口,参数不认识string这样的类,所以传参一般要传字符串的首字符地址,就可以使用c_str()这个接口将string类转换为地址,返回值为const char*
9.find、rfind、substr
void test_string10()
{
//查找文件后缀
//从前向后找
cout << "1." << endl;
string s1("string.cpp");
size_t pos1 = s1.find(".");
cout << s1.substr(pos1) << endl;
//从后向前找
cout << "2." << endl;
string s2("hello.world.cpp");
size_t pos2 = s2.rfind(".");
cout << s2.substr(pos2) << endl;
}
注意:find()中传的参数要全部匹配上才可以,与下一条(10.)有明显区别
10.?find_first_of、find_last_of、find_first_not_of、find_last_not_of
void test_string11()
{
cout << "1." << endl;
string s1("hello,This,is,my,world!");
size_t pos1 = 0;
while (1)
{
pos1 = s1.find_first_of("l,!");
if (pos1 == string::npos)
break;
s1[pos1] = '*';
cout << s1 << endl;
}
cout << "2." << endl;
string s2("hello,This,is,my,world!");
size_t pos2 = 0;
while (1)
{
pos2 = s2.find_first_not_of("l,!");
if (pos2 == string::npos)
break;
s2[pos2] = ',';
cout << s2 << endl;
}
cout << "3." << endl;
string s3("hello,This,is,my,world!");
size_t pos3 = 0;
while (1)
{
pos3 = s3.find_last_of("l,!");
if (pos3 == string::npos)
break;
s3[pos3] = '*';
cout << s3 << endl;
}
}
find_first_of、find_last_of:只要有一个匹配上即可
find_first_not_of、find_last_not_of:只要不是这些字符的任意一个即可
除此之外string支持比较大小、支持加法、operator>>/<<,以上为string类使用的高频接口,只讲解了重点,如果想要更全面细致了解,请到下面官方网址查阅官方资料
string - C++ Reference
|