STL详解string类
Posted Soryu_Shikinami
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL详解string类相关的知识,希望对你有一定的参考价值。
目录
1.标准库中的string类
总结:
1.) string是表示字符串的字符串类。
2. )该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。3. )string在底层实际是:basic_string模板类的别名,typedef basic_string<char,char_traits, allocator>string;
4. )不能操作多字节或者变长字符的序列。
string类的常用接口说明:
1. string类对象的常见构造
(constructor)函数名称 | 功能说明 |
string() (重点) | 构造空的string类对象,即空字符串 |
string(const char* s) (重点) | 用C-string来构造string类对象 |
string(size_t n, char c) | string类对象中包含n个字符c |
string(const string&s) (重点) | 拷贝构造函数 |
string(); //构造一个空字符串
string(const char* s); //复制s所指的字符序列
string(const char* s, size_t n); //复制s所指字符序列的前n个字符
string(size_t n, char c); //生成n个c字符的字符串
string(const string& str); //生成str的复制品
string(const string& str, size_t pos, size_t len = npos); //复制str中从字符位置pos开始并跨越len个字符的部分
使用示例:
string s1; //构造空字符串
string s2("hello"); //复制"hello string"
string s3("hello", 3); //复制"hello string"的前3个字符
string s4(10, 's'); //生成10个's'字符的字符串
string s5(s2); //生成s2的复制品
string s6(s2, 1, 4); //复制s2中从字符位置1开始并跨越4个字符的部分
2.2string类对象的容量操作
函数名称 | 功能说明 |
size | 返回字符串有效字符长度 |
length | 返回字符串有效字符长度 |
capacity | 返回空间总大小 |
empty | 检测字符串释放为空串,是返回true,否则返回false |
clear | 清空有效字符 |
reserve | 为字符串预留空间 |
resize | 将有效字符的个数该成n个,多出的空间用字符c填充 |
使用示例:
1、使用size函数或length函数获取当前有效字符的个数
size_t size() const;
size_t length() const;
string s("CSDN");
cout << s.size() << endl; //4
cout << s.length() << endl; //4
2、 使用capacity函数获取当前对象所分配的存储空间的大小
size_t capacity() const;
string s("CSDN");
cout << s.capacity() << endl; //15
3、使用resize改变当前对象的有效字符的个数
void resize (size_t n);
void resize (size_t n, char c);
resize规则:
1、当n大于对象当前的size时,将size扩大到n,扩大的字符为c,若c未给出,则默认为’\\0’。
2、当n小于对象当前的size时,将size缩小到n。
使用实例:
string s1("ABCD");
//resize(n)n大于对象当前的size时,将size扩大到n,扩大的字符默认为'\\0'
s1.resize(20);
cout << s1 << endl; //ABCD
cout << s1.size() << endl; //20
cout << s1.capacity() << endl; //31
string s2("ABCD");
//resize(n, char)n大于对象当前的size时,将size扩大到n,扩大的字符为char
s2.resize(20, 'x');
cout << s2 << endl; //ABCDxxxxxxxxxxxxxxxx
cout << s2.size() << endl; //20
cout << s2.capacity() << endl; //31
string s3("ABCD");
//resize(n)n小于对象当前的size时,将size缩小到n
s3.resize(2);
cout << s3 << endl; //AB
cout << s3.size() << endl; //2
cout << s3.capacity() << endl; //15
注意:若给出的n大于对象当前的capacity,则capacity也会根据自己的增长规则进行扩大。
4、使用reserve改变当前对象的容量大小
void reserve (size_t n = 0);
reserve规则:
1、当n大于对象当前的capacity时,将capacity扩大到n或大于n。
2、当n小于对象当前的capacity时,什么也不做。
使用示例:
string s("ABCD");
cout << s << endl; //ABCD
cout << s.size() << endl; //4
cout << s.capacity() << endl; //15
//reverse(n)当n大于对象当前的capacity时,将当前对象的capacity扩大为n或大于n
s.reserve(20);
cout << s << endl; //ABCD
cout << s.size() << endl; //4
cout << s.capacity() << endl; //31
//reverse(n)当n小于对象当前的capacity时,什么也不做
s.reserve(2);
cout << s << endl; //ABCD
cout << s.size() << endl; //4
cout << s.capacity() << endl; //31
注意:此函数对字符串的size没有影响,并且无法更改其内容。
以上小结:
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不会改变容量大小。
3. string类对象的访问及遍历操作
函数名称 | 功能说明 |
operator[] | 返回pos位置的字符,const string类对象调用 |
begin | 获取第一个字符的迭代器 |
end | 获取最后一个字符下一个位置的迭代器 |
rbegin | 返回指向字符串最后一个字符的反向迭代器 |
rend | 返回指向字符串第一个字符前面的理论元素的反向迭代器 |
范围for | C++11支持更简洁的范围for的新遍历方式 |
1、[ ]+下标
因为string类对[ ]运算符进行了重载,所以我们可以直接使用[ ]+下标访问对象中的元素。并且该重载使用的是引用返回,所以我们可以通过[ ]+下标修改对应位置的元素。
char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
string s("ABCD");
//[]+下标访问对象元素
for (size_t i = 0; i < s.size(); i++)
cout << s[i];
cout << endl;
//[]+下标修改对象元素内容
for (size_t i = 0; i < s.size(); i++)
s[i] = 'a';
cout << s << endl; //aaaa
2、使用迭代器访问对象中的元素
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
string s("ABCD");
//使用迭代器访问对象元素
string::iterator it1 = s.begin();
while (it1 != s.end())
cout << *it1;
it1++;
cout << endl; //ABCD
//使用迭代器访问对象元素,并对其进行修改
string::iterator it2 = s.begin();
while (it2 != s.end())
*it2 += 1;
it2++;
cout << s << endl; //DCBA
3、使用范围for访问对象中的元素
需要注意的是:若是需要通过范围for修改对象的元素,则用于接收元素的变量e的类型必须是引用类型,否则e只是对象元素的拷贝,对e的修改不会影响到对象的元素。
string s("ABCD");
//使用范围for访问对象元素
for (auto e : s)
cout << e;
cout << endl; //CSDN
//使用范围for访问对象元素,并对其进行修改
for (auto& e : s) //需要修改对象的元素,e必须是引用类型
e = 'x';
cout << s << endl; //xxxx
4. string类对象的修改操作
函数名称 | 功能说明 |
push_back | 在字符串后尾插字符c |
append | 在字符串后追加一个字符串 |
operator+= | 在字符串后追加字符串str |
c_str | 返回C格式字符串 |
find + npos | 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置 |
rfind | 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置 |
substr | 在str中从pos位置开始,截取n个字符,然后将其返回 |
使用实例:
#include <iostream>
#include <string>
using namespace std;
void Teststring()
string str;
str.push_back(' '); // 在str后插入空格
str.append("hello"); // 在str后追加一个字符"hello"
str += 'l'; // 在str后追加一个字符'l'
str += "xy"; // 在str后追加一个字符串"xy"
cout << str << endl; // hellolxy
cout << str.c_str() << endl; // 以C语言的方式打印字符串
// 获取file的后缀
string file("string.cpp");
size_t pos = file.rfind('.');
string suffix(file.substr(pos, file.size() - pos));
cout << suffix << endl; //cpp
// npos是string里面的一个静态成员变量
// static const size_t npos = -1;
// 取出url中的域名
string url("http://www.cplusplus.com/reference/string/string/find/");
cout << url << endl;
size_t start = url.find("://");
if (start == string::npos)
cout << "invalid url" << endl;
return;
start += 3; // 指向W
size_t finish = url.find('/', start); //从start向后开始找'/'
string address = url.substr(start, finish - start);
cout << address << endl; //www.cplusplus.com
// 删除url的协议前缀
pos = url.find("://");
url.erase(0, pos + 3);
cout << url << endl; //www.cplusplus.com/reference/string/string/find/
int main()
Teststring();
return 0;
1、使用c_str或data将string转换为字符串
const char* c_str() const;
const char* data() const;
区别:
- 在C++98中,c_str()返回 const char* 类型,返回的字符串会以空字符结尾。
- 在C++98中,data()返回 const char* 类型,返回的字符串不以空字符结尾。
- 但是在C++11版本中,c_str()与data()用法相同。
string s("hello world ");
const char* str1 = s.data();
const char* str2 = s.c_str();
cout << str1 << endl;
cout << str2 << endl;
2、使用substr函数提取string中的子字符串
string substr (size_t pos = 0, size_t len = npos) const;
string s1("abcdef");
string s2;
//substr(pos, n)提取pos位置开始的n个字符序列作为返回值
s2 = s1.substr(2, 3);
cout << s2 << endl; //cde
注意:
1. )在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
2. )对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
5. string类非成员函数
函数 | 功能说明 |
operator+ | 尽量少用,因为传值返回,导致深拷贝效率低 |
operator>> | 输入运算符重载 |
operator<< | 输出运算符重载 |
getline | 获取一行字符串 |
relational operators | 大小比较 |
1、operator+
string类中对+运算符进行了重载,重载后的+运算符支持以下几种类型的操作:
1.)string类 + string类
2.)string类 + 字符串
3.)字符串 + string类
4.)string类 + 字符
5.)字符 + string类
它们相加后均返回一个string类对象。
2、operator>> 和 operator<<
string类中也对>>和<<运算符进行了重载,这就是为什么我们可以直接使用>>和<<对string类进行输入和输出的原因。
3、relational operators
string类中还对一系列关系运算符进行了重载,它们分别是==、!=、<、<=、>、>=。重载后的关系运算符支持string类和string类之间的关系比较、string类和字符串之间的关系比较、字符串和string类之间的关系比较。
4、getline函数
1.)istream& getline (istream& is, string& str);
getline函数将从is中提取到的字符存储到str中,直到读取到换行符’\\n’为止。
string s;
getline(cin, s); //输入:hello lxy
cout << s << endl; //输出:hello lxy
2.) istream& getline (istream& is, string& str, char delim);
getline函数将从is中提取到的字符存储到str中,直到读取到分隔符delim或换行符’\\n’为止。
string s;
getline(cin, s, 'x'); //输入:hello lxy
cout << s << endl; //输出:hello l
以上是关于STL详解string类的主要内容,如果未能解决你的问题,请参考以下文章