目录
一、string
1、string的介绍
string是管理字符数组的类。
typedef basic_string<char> string;
basic_string是模板。将basic_string<char>这个实例重命名为string。
2、为什么string类要实现为模板?
我们印象中,单个字符就是1个字节,也就是char类型,但是由于编码问题,会有2字节和4字节的字符类型。
类型 |
编码 |
类型 |
string |
UTF-8 |
char |
wstring |
Unicode |
wchar_t |
u16string |
UTF-16 |
char16_t |
u32string |
UTF-32 |
char32_t |
对于字符串的多种类型,设计了basic_string模板。
二、元素访问
1、使用operator[]实现数组下标式的访问
int main()
{
string s("hello world");//构造
for (size_t i = 0; i < s.size(); ++i)//读
{
cout << s[i] << " ";//等价于cout << s.operator[](i) << " ";
}
cout<<endl;
for (size_t i = 0; i < s.size(); ++i)//写
{
cout << (s[i] += 1) << " ";
}
return 0;
}
operator[]和at的区别在于operator[]是断言,at是抛异常。主要release版本assert失效。
2、迭代器读写
2.1正向迭代器
int main()
{
string s("hello world");
string::iterator it = s.begin();
//遍历访问
while (it != s.end())
{
cout << *it;
++it;
}
cout << endl;
it = s.begin();//将it重新置为s.begin位置
//遍历修改
while (it != s.end())
{
*it += 1;
cout << *it;
++it;
}
return 0;
}
2.2反向迭代器
int main()
{
string s("hello world");
string::reverse_iterator rit = s.rbegin();
//遍历访问
while (rit != s.rend())
{
cout << *rit;
++rit;
}
cout << endl;
//遍历修改
rit = s.rbegin();//将rit重新置为s.rbegin位置
while (rit != s.rend())
{
*rit += 1;
cout << *rit;
++rit;
}
return 0;
}
2.3const正向迭代器(不能改变*it)
void test(const string& s)
{
string::const_iterator it = s.begin();
while (it != s.end())
{
cout << *it;
++it;
}
}
2.4const反向迭代器(不能改变*it)
void test(const string& s)
{
string::const_reverse_iterator rit = s.rbegin();
while (rit != s.rend())
{
cout << *rit;
++rit;
}
}
3、范围for读写
int main()
{
string s("hello world");
//范围for的遍历访问
for (auto e : s)
{
cout << e;
}
cout << endl;
//范围for的遍历修改
for (auto& e : s)
{
e += 1;
cout << e;
}
return 0;
}
三、string的构造接口
函数名称 |
功能说明 |
|
string() (重点) |
无参的构造,构造空字符串 |
|
string(const char* s) (重点) |
用C_string字符串构造对象 |
|
string(size_t n, char c) |
用n个字符创建对象 |
|
string(const string& s) (重点) |
拷贝构造 |
|
string (const string& str, size_t pos, size_t len = npos) |
用对象构造,下标为2至len位置 |
|
string (const char* s, size_t n) |
用字符串的前n个构造对象 |
|
template <class InputIterator> string (InputIterator first, InputIterator last); |
迭代器区间构造 |
int main()
{
string s1;//无参的构造
string s2("hello world");//用C_string字符串构造对象
string s3(3, 'x');//用3个字符创建对象
string s4(s2);//拷贝构造
string s5(s2, 2, 7);//用s2对象构造,下标为2开始,共7个字符构造s5,结果为llo wor
string s6("hello world", 7);//用字符串构前7个字符构造
string s7(s2.begin(),s2.begin()+3);//迭代器区间构造
return 0;
}
四、string的容量相关的接口
函数名称 |
功能说明 |
size(重点) |
返回字符串的长度,不包含'\0' |
length |
返回字符串的长度,不包含'\0' |
capacity |
返回数组容量 |
empty(重点) |
字符串的判空 |
clear(重点) |
将size置为0,不改变容量 |
reserve(重点) |
用于预先开好空间 |
resize(重点) |
调整size的大小,可能会改变容量。多出来的位置用'\0'填充 |
1.reserve(调整容量)
reserve用于预先开好空间,如果预开空间小于现有空间,将不会改变容量。
2.resize(调整size)
int main()
{
string s("hello world");
s.resize(20, 'x');//将size改为20,多出来的位置用字符x填充
s.resize(30);//将size改为30,多出来的位置用'\0'填充
return 0;
}
reserve和resize扩容时不会对已有的数据做改变,但缩容时会放弃超出空间的已有数据。
五、string对象修改相关的接口
函数名称 |
功能说明 |
push_back |
尾插一个字符 |
append |
尾插字符串 |
operator+=(重点) |
字符、字符串尾插 |
insert |
在pos位置插入 |
earse |
在pos位置删除 |
assign |
对原有字符串清空后赋值 |
replace |
替换 |
1、insert
string& insert (size_t pos, const string& str);//pos位置插入string对象
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);//pos位置插入字符对象的一部分
string& insert (size_t pos, const char* s);//pos位置插入字符串
string& insert (size_t pos, const char* s, size_t n);//pos位置插入字符串的前n个
string& insert (size_t pos, size_t n, char c);//在pos位置插入n个字符
void insert (iterator p, size_t n, char c);
iterator insert (iterator p, char c);
template <class InputIterator>
void insert (iterator p, InputIterator first, InputIterator last);
2、earse
string& erase (size_t pos = 0, size_t len = npos); //从pos位置删除len个字符
iterator erase (iterator p);
iterator erase (iterator first, iterator last);
3、assign
assign可以理解成将原字符对象清空,重新进行赋值操作。
4、replace
repalce是对字符对象的部分取代。
#include <iostream>
#include <string>
#include <cstddef>
int main ()
{
std::string str ("The sixth sick sheik's sixth sheep's sick.");
std::string key ("sixth");
std::size_t found = str.rfind(key);
if (found!=std::string::npos)
str.replace (found,key.length(),"seventh");
std::cout << str << '\n';
return 0;
}
六、string对象字符串运算相关接口
c_str(重点) |
将string对象返回c格式字符串的指针 |
find(重点) |
查找 |
rfind |
倒着找 |
substr(重点) |
返回子串 |
find_first_of |
返回第一个匹配字符的下标 |
1、c_str
int main()
{
string s("hello world");
//虽然打印结果一样,但c_str()返回const char*,可以用于返回值有要求的地方
cout << s << endl;
cout << s.c_str() << endl;
string file("test.txt");
FILE* fout = fopen(file.c_str(), "w");
return 0;
}
2、find查找+substr返回子串
size_t find (const string& str, size_t pos = 0) const;//从pos位置开始,在string对象中找str
size_t find (const char* s, size_t pos = 0) const;//从pos位置开始,在string对象中找s
size_t find (const char* s, size_t pos, size_t n) const;//从pos位置开始,在string对象中匹配s的前n个
size_t find (char c, size_t pos = 0) const;//从pos位置开始,在string对象中找字符
rfind是找到字符最后一次出现位置的下标。
一闭一开才是真实距离!!!
查找.后边的内容:
int main()
{
string file("test.txt");
size_t pos = file.find('.');//size_t find (char c, size_t pos = 0) const;
if (pos != string::npos)//npos是定义在string中的静态变量
{
string suffix = file.substr(pos,file.size()-pos);//这里长度不给也行,默认是npos
cout << suffix << endl;
}
return 0;
}
查找协议:
int main()
{
string url("https://legacy.cplusplus.com/reference/string/string/find/");
size_t pos = url.find(':');
if (pos != string::npos)
{
string protocol = url.substr(0, pos);//从0开始数pos个元素
cout << protocol << endl;
}
return 0;
}
查找域名:
int main()
{
string url("https://legacy.cplusplus.com/reference/string/string/find/");
size_t pos1 = url.find(':');
size_t pos2 = url.find('/', pos1 + 3);
if (pos2 != string::npos)
{
string domainName = url.substr(pos1+3, pos2-pos1-3);
cout << domainName << endl;
}
return 0;
}
查找地址:
int main()
{
string url("https://legacy.cplusplus.com/reference/string/string/find/");
size_t pos1 = url.find(':');
size_t pos2 = url.find('/', pos1 + 3);
string uri = url.substr(pos2+1);
cout << uri << endl;
return 0;
}
七、部分非成员函数接口
函数名称 |
功能说明 |
operator+ |
左右操作数必须有一个string对象或 |
operator<< |
流插入 |
operator>> |
流提取 |
getline(重点) |
获取一行 |
流提取是不能接收到空格和换行的,需要接收一行的时候需要使用getline。
1、getline
istream& getline (istream& is, string& str, char delim);//从流提取中取出字符至str中,直至遇到delim或'\n'
istream& getline (istream& is, string& str);//从流提取中取出字符至str中
getline(std::cin,str);
八、string对象与其他类型互相转换
1、stoi等
将一个string对象转化为int类型的数字。
idx如果不传或者为nullptr,则表示不使用这个参数;反之,&idx指向string对象数字字符的后一个位置。
2、to_string
能够把内置类型转化为string对象。