【STL详解】string类

目录

1.标准库中的string类

string类的常用接口说明:

1. string类对象的常见构造

2.2string类对象的容量操作

3. string类对象的访问及遍历操作 

4. string类对象的修改操作

5. 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未给出,则默认为’’。
 2、当n小于对象当前的size时,将size缩小到n。

使用实例:

	string s1("ABCD");
	//resize(n)n大于对象当前的size时,将size扩大到n,扩大的字符默认为''
	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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>