IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【STL详解】string类 -> 正文阅读

[游戏开发]【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未给出,则默认为’\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?返回指向字符串第一个字符前面的理论元素的??反向迭代器?
范围forC++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

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:59:49  更:2022-03-30 19:00:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:52:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码