目录
前言
本篇文章目的是为了快速掌握string的使用,这里对常用的进行演示助于理解,其它的也会给出。
一、基本知识
1、如果要使用string类,那么必须包含头文件以及using namespace std;
2、该接口与常规的容器基本相同,再添加了一些专门用来操作的string的常规操作
3、string是表示字符串的字符串类
4、不能操作多字节或者边长字符的序列
5、string在底层实际是:basic_string模版类的别名
二、常用接口使用
2.1常见构造
函数名称 | 功能说明 |
string() (重点) | 构造空的string类对象,即空字符串 |
string(const char* s) (重点) | 用C-string来构造string类对象 |
string(size_t n, char c) | string类对象中包含n个字符c |
string(const string&s) (重点) | 拷贝构造函数 |
string (const string& str, size_t pos, size_t len = npos); |
复制从字符位置 pos 开始并跨越 len 字符的 str 部分(如果 str 太短或 len 是 string::npos,则复制到 str 的末尾)。 |
//无参构造
string s1;
//常量字符串初始化
string s2("李白");
string s3("hello world");
//n个字符进行初始化,10个*
string s4(10, '*');
//拷贝构造
string s5(s2);
string s6(s3, 6, 5);//从s3的第6个开始,往后复制5个有效字符给s6
string s7(s3, 6);//从s3里复制前6个字符给s7
2.2容量操作
函数名称 | 功能说明 |
size(重点) | 返回字符串有效字符长度 |
length | 返回字符串有效字符长度 |
max_size | 返回字符串的最大长度 |
capacity | 返回空间总大小 |
empty (重点) | 检测字符串释放为空串,是返回true,否则返回false |
clear (重点) | 清空有效字符 |
reserve (重点) void reserve (size_t n = 0); |
为字符串预留空间,如果 n 大于当前字符串容量,则该函数会导致容器将其容量增加到 n 个字符(或更大)。 |
resize (重点) void resize (size_t n); |
将有效字符的个数改成n个,多出的空间用字符c填充; |
#include<string>
#include<iostream>
using namespace std;
int main()
{
string s1("hello world");
cout << s1.size() << endl;//有效字符,不算\0
cout << s1.length() << endl;//有效字符,不算\0
cout << s1.capacity() << endl;//容量
cout << s1.max_size() << endl;//最大容量
cout << s1.empty() << endl;//是否为空
return 0;
}
std::string.capacity( )此容量不一定等于字符串长度。它可以等于或更大,额外的空间允许对象在向字符串添加新字符时优化其作,而且不同的平台在不一样。
#include<string>
#include<iostream>
using namespace std;
int main()
{
string s1("hello world");
cout << s1.capacity() << endl;
s1.reserve(20);//扩容
cout << s1.capacity() << endl;
s1.resize(5);//有效字符设为5
cout << s1 << endl;
s1.resize(10, 'x');//有效字符设为10,多的部分初始化字符'x'
cout << s1 << endl;
return 0;
}
string的扩容机制每个平台也是不一样的,如果是用linux的话,会是准确的。
注意:
1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
2. clear()只是将string中有效字符清空,不改变底层空间大小。
3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
2.3string类对象的访问及遍历操作
函数名称 | 功能说明 |
operator[] (重点) | 返回pos位置的字符,const string类对象调用 |
at |
返回pos位置的字符,const string类对象调用 |
back | C++11返回最后一个字符 |
front | C++11返回第一个字符 |
begin+ end | begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器 |
rbegin + rend | begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器 |
范围for(方便) | C++11支持更简洁的范围for的新遍历方式 |
#include<string>
#include<iostream>
using namespace std;
int main()
{
string s1("hello world");
cout << s1[0] << endl;//访问下标为0的字符
cout << s1.at(0) << endl;//访问下标为0的字符
cout << s1.front() << endl;//访问头字符
cout << s1.back() << endl;//访问尾字符
for (auto x : s1)//语法糖,范围for
{
cout << x;
}
cout << endl;
string::iterator it= s1.begin();//正向迭代器
while (it != s1.end())
{
cout << *it;
it++;
}
cout << endl;
string::reverse_iterator il = s1.rbegin();//反向迭代器
while (il != s1.rend())
{
cout << *il;
il++;
}
cout << endl;
return 0;
}
1.范围for,不能倒着遍历,只有正着遍历,范围for底层就是替换为迭代器。
2.迭代器是通用的,任何容器都支持迭代器,一通百通,并且用法类似,iterator提供了一种统一的方式访问和修改容器的数据。
2.3string类对象的修改操作
函数名称 | 功能说明 |
push_back | 在字符串后尾插字符c |
append | 在字符串后追加一个字符串 |
operator+= (重点) | 在字符串后追加字符串str |
assign | 原来的字符串数据不要了,重新给数据,用的较少 |
replace | 替换字符 |
erase string& erase (size_t pos = 0, size_t len = npos); iterator erase (iterator p); iterator erase (iterator first, iterator last); |
从字符串中删除,从pos开始,删除len个 或者迭代器删除 |
c_str(重点) | 返回C格式字符串 |
find + npos(重点) | 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置 |
rfind | 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置 |
substr | 在str中从pos位置开始,截取n个字符,然后将其返回 |
#include<string>
#include<iostream>
using namespace std;
int main()
{
string s1("hello world");
s1.push_back('s');
s1.append(" world");
s1 += '*';
s1 += "www";
cout << s1 << endl;
s1.assign("hello world");//清除原有数据,载入新的数据
cout << s1 << endl;
s1.replace(6, 5, "11111111");//下标从6开始,后面的5个字符替换成str
cout << s1 << endl;
cout << s1.c_str() << endl;
s1.erase(0,5);//下标从0开始,删除5个
cout << s1 << endl;
cout << s1.substr(0, 5)<< endl;//下标从0开始,截取字符串中的5个
s1.erase(0);//下标从0开始,后面全部删除
cout << s1 << endl;
return 0;
}
将协议 域名 资源名分离:
#include<string>
#include<iostream>
using namespace std;
int main()
{
//将协议 域名 资源名分离
string url("https://legacy.cplusplus.com/reference/string/string");
size_t pos1 = url.find("://");//如果找到了返回第一个字符的位置,没找到返回npos
string protocol;
if (pos1 != string::npos)
{
protocol = url.substr(0, pos1);
}
cout << protocol << 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;
return 0;
}
2.4非成员函数
函数 | 功能说明 |
operator+ | 尽量少用,因为传值返回,导致深拷贝效率低 |
operator>> (重点) | 输入运算符重载 |
operator<< (重点) | 输出运算符重载 |
getline (重点) | 获取一行字符串 |
relational operators (重点) | 大小比较 |
其它的可以在这里查看:string - C++ Referencehttps://legacy.cplusplus.com/reference/string/string/?kw=string
总结
本文简单的介绍string,方便使用,快速入手。