C++初阶(十一)--STL--string类

目录

一、string类的概述

二、string类的创建与初始化

1. 直接初始化

2. 无参初始化

3. 从字符数组初始化

三、string类的基本操作

1.string的定义方式

2.string的插入

3.string的拼接 

4.string的删除

5.string的查找

6.string的比较

7.string的大小和容量

8.string中与迭代器相关的函数

9.string中的操作符

10.string中元素的访问

11.string中的getline函数


一、string类的概述

在 C++ 中,string类是用于处理字符串的标准类。它提供了一种方便、灵活且功能强大的方式来操作字符序列,相较于传统的 C 风格字符数组,string类隐藏了许多底层的内存管理细节,让程序员能够更专注于字符串本身的处理逻辑。

二、string类的创建与初始化

1. 直接初始化

可以使用双引号括起来的字符串常量直接初始化一个string对象,就像这样:

string str1 = "Hello";

2. 无参初始化

也可以先创建一个空的string对象,然后再根据需要进行赋值等操作,例如:

string str2;
str2 = "World";

首先创建了一个空的string对象str2,之后通过赋值操作将其设置为 "World"。

3. 从字符数组初始化

如果已经有一个 C 风格的字符数组,也可以用它来初始化string对象,如下:

char charArray[] = {'H', 'e', 'l', 'l', 'o'};
string str3(charArray);

 这里通过string类的构造函数,将字符数组charArray转换为了string对象str3

三、string类的基本操作

学习这一部分,我们一定要学会看文档,虽然通过基础的学习和一些常见示例可以掌握其主要的操作方法,比如字符串拼接、查找、截取等,但它还有很多细节之处以及一些不那么常用但在特定场景下很关键的功能。文档会全面且详细地列出string类所提供的所有成员函数、它们的具体用法、参数含义以及返回值情况等。

点击:文档的网址

1.string的定义方式

string类实现了多个构造函数的重载,常用的构造函数如下:

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 string");     //复制"hello string"
string s3("hello string", 3);  //复制"hello string"的前3个字符
string s4(10, 's');            //生成10个's'字符的字符串
string s5(s2);                 //生成s2的复制品
string s6(s2, 0, 4);           //复制s2中从字符位置0开始并跨越4个字符的部分

 以上的这些在文档中都是有的。

 下面是使用方法,如果看不懂,可以借助翻译软件,但建议尽量培养独自阅读英文文档的能力。

 2.string的插入

使用push_back进行尾插

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;
	s.push_back('C');
	s.push_back('S');
	s.push_back('D');
	s.push_back('N');
	cout << s << endl; //CSDN
	return 0;
}

使用insert插入

接下来我们只举部分的列子,详细内容可以查看文档

string& insert (size_t pos, const string& str);
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
string& insert (size_t pos, const char* s);
iterator insert (iterator p, char c); 

 示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("C"); //C
	string s1("hello world");
	string s2("123");
	//insert(pos, str)在pos位置插入字符串str
	s.insert(1, "S"); //CS

	//insert (pos, str, subpos,sublen);在s1的pos位置追加s2的sublen个字符,并且从s2的subpos位置拿数据开始
	s1.insert(5, s2, 1, 2);//hellow3 world
	//insert(pos, string)在pos位置插入string对象
	string t("D");
	s.insert(2, t); //CSD

	//insert(pos, char)在pos位置插入字符char
	s.insert(s.end(), 'N'); //CSDN

	cout << s << endl; //CSDN
	cout << s1 << endl;
	return 0;
}

3.string的拼接 

使用append函数完成string的拼接:

代码示例: 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("I");
	string s2(" like");

	//append(string)完成两个string对象的拼接
	s1.append(s2); //I like

	//append(str)完成string对象和字符串str的拼接
	s1.append(" C++"); //I like C++

	//append(n, char)将n个字符char拼接到string对象后面
	s1.append(3, '!'); //I like C++!!!
	
	cout << s1 << endl; //I like C++!!!
	return 0;
}

 4.string的删除

使用pop_back进行尾删

 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("C++");
	s.pop_back();
	s.pop_back();
	cout << s << endl; //C
	return 0;
}

 使用erase删除

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("I like C++!!!");

	//erase(pos, n)删除pos位置开始的n个字符
	s.erase(8, 5); //I like C

	//erase(pos)删除pos位置的字符
	s.erase(s.end()-1); //I like

	//erase(pos1, pos2)删除[pos1pos2)上所有字符
	s.erase(s.begin() + 1, s.end()); //I

	cout << s << endl; //I
	return 0;
}

5.string的查找

使用find函数正向搜索第一个匹配项

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");

	//find(string)正向搜索与string对象所匹配的第一个位置
	string s2("www");
	size_t pos1 = s1.find(s2);
	cout << pos1 << endl; //7

	//find(str)正向搜索与字符串str所匹配的第一个位置
	char str[] = "cplusplus.com";
	size_t pos2 = s1.find(str);
	cout << pos2 << endl;  //11

	//find(char)正向搜索与字符char所匹配的第一个位置
	size_t pos3 = s1.find(':');
	cout << pos3 << endl; //4
	return 0;
}

使用rfind函数反向搜索第一个匹配项 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");

	//rfind(string)反向搜索与string对象所匹配的第一个位置
	string s2("string");
	size_t pos1 = s1.rfind(s2);
	cout << pos1 << endl; //42

	//rfind(str)反向搜索与字符串str所匹配的第一个位置
	char str[] = "reference";
	size_t pos2 = s1.rfind(str);
	cout << pos2 << endl;  //25

	//rfind(char)反向搜索与字符char所匹配的第一个位置
	size_t pos3 = s1.rfind('/');
	cout << pos3 << endl; //53
	return 0;
}

 6.string的比较

使用compare函数完成比较:

比较规则:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("hello world");
	string s2("hello CSDN");

	//"hello world"和"hello CSDN"比较
	cout << s1.compare(s2) << endl; //1

	//"ell"和"hello CSDN"比较
	cout << s1.compare(1, 3, s2) << endl; //-1

	//"hello"和"hello"比较
	cout << s1.compare(0, 4, s2, 0, 4) << endl; //0

	return 0;
}

7.string的大小和容量

使用size函数或length函数获取当前有效字符的个数

这个比较简单,但我们很多地方要用到,只举例代码:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");
	cout << s.size() << endl; //4
	cout << s.length() << endl; //4
	return 0;
}

使用max_size函数获取string对象对多可包含的字符数

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");
	cout << s.max_size() << endl; //4294967294
	return 0;
}

 使用capacity函数获取当前对象所分配的存储空间的大小

 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");
	cout << s.capacity() << endl; //15
	return 0;
}

使用resize改变当前对象的有效字符的个数

 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("CSDN");
	//resize(n)n大于对象当前的size时,将size扩大到n,扩大的字符默认为'\0'
	s1.resize(20);
	cout << s1 << endl; //CSDN
	cout << s1.size() << endl; //20
	cout << s1.capacity() << endl; //31

	string s2("CSDN");
	//resize(n, char)n大于对象当前的size时,将size扩大到n,扩大的字符为char
	s2.resize(20, 'x');
	cout << s2 << endl; //CSDNxxxxxxxxxxxxxxxx
	cout << s2.size() << endl; //20
	cout << s2.capacity() << endl; //31

	string s3("CSDN");
	//resize(n)n小于对象当前的size时,将size缩小到n
	s3.resize(2);
	cout << s3 << endl; //CS
	cout << s3.size() << endl; //2
	cout << s3.capacity() << endl; //15
	return 0;
}

注意:若给出的n大于对象当前的capacity,则capacity也会根据自己的增长规则进行扩大。 

 使用reserve改变当前对象的容量大小

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");
	cout << s << endl; //CSDN
	cout << s.size() << endl; //4
	cout << s.capacity() << endl; //15

	//reverse(n)当n大于对象当前的capacity时,将当前对象的capacity扩大为n或大于n
	s.reserve(20); 
	cout << s << endl; //CDSN
	cout << s.size() << endl; //4
	cout << s.capacity() << endl; //31

	//reverse(n)当n小于对象当前的capacity时,什么也不做
	s.reserve(2);
	cout << s << endl; //CDSN
	cout << s.size() << endl; //4
	cout << s.capacity() << endl; //31
	return 0;
}

注意:此函数对字符串的size没有影响,并且无法更改其内容

使用clear删除对象的内容,删除后对象变为空字符串

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");

	//clear()删除对象的内容,该对象将变为空字符串
	s.clear();
	cout << s << endl; //空字符串
	return 0;
}

 使用empty判断对象是否为空

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");
	cout << s.empty() << endl; //0

	//clear()删除对象的内容,该对象将变为空字符串
	s.clear();
	cout << s.empty() << endl; //1
	return 0;
}

8.string中与迭代器相关的函数

与正向迭代器相关的函数
begin函数:返回一个指向字符串第一个字符的迭代器。

 end函数:返回一个指向字符串结束字符的迭代器,即’\0’。

 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello string");

	//正向迭代器
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it;
		it++;
	}
	cout << endl; //hello string

	return 0;
}

 与反向迭代器相关的函数
rbegin函数:返回指向字符串最后一个字符的反向迭代器。

 rend函数:返回指向字符串第一个字符前面的理论元素的反向迭代器。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello string");

	//反向迭代器
	string::reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit;
		rit++;
	}
	cout << endl; //gnirts olleh

	return 0;
}

9.string中的操作符

operator=

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1;
	string s2("CSDN");

	//支持string类的赋值
	s1 = s2;
	cout << s1 << endl; //CSDN

	//支持字符串的赋值
	s1 = "hello";
	cout << s1 << endl;  //hello

	//支持字符的赋值
	s1 = 'x';
	cout << s1 << endl; //x
	return 0;
}

 operator+=

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1;
	string s2("hello");

	//支持string类的复合赋值
	s1 += s2;
	cout << s1 << endl; //hello

	//支持字符串的复合赋值
	s1 += " CSDN";
	cout << s1 << endl; //hello CSDN

	//支持字符的复合赋值
	s1 += '!';
	cout << s1 << endl; //hello CSDN!
	return 0;
}

operator+

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;
	string s1("super");
	string s2("man");
	char str[] = "woman";
	char ch = '!';

	//string类 + string类
	s = s1 + s2;
	cout << s << endl; //superman

	//string类 + 字符串
	s = s1 + str;
	cout << s << endl; //superwoman

	//字符串 + string类
	s = str + s1;
	cout << s << endl; //womansuper

	//string类 + 字符
	s = s1 + ch;
	cout << s << endl; //super!
	
	//字符 + string类
	s = ch + s1;
	cout << s << endl; //!super
	return 0;
}

operator>> 和 operator<<

string类中也对>>和<<运算符进行了重载,这就是为什么我们可以直接使用>>和<<对string类进行输入和输出的原因。

istream& operator>> (istream& is, string& str);
ostream& operator<< (ostream& os, const string& str);

 代码示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;
	cin >> s; //输入
	cout << s << endl; //输出
	return 0;
}

10.string中元素的访问

[ ]+下标
 因为string类对[ ]运算符进行了重载,所以我们可以直接使用[ ]+下标访问对象中的元素。并且该重载使用的是引用返回,所以我们可以通过[ ]+下标修改对应位置的元素。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");
	//[]+下标访问对象元素
	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] = 'x';
	}
	cout << s << endl; //xxxx
	return 0;
}

 使用at访问对象中的元素
 因为at函数也是使用的引用返回,所以我们也可以通过at函数修改对应位置的元素

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");
	for (size_t i = 0; i < s.size(); i++)
	{
		//at(pos)访问pos位置的元素
		cout << s.at(i);
	}
	cout << endl;

	for (size_t i = 0; i < s.size(); i++)
	{
		//at(pos)访问pos位置的元素,并对其进行修改
		s.at(i) = 'x';
	}
	cout << s << endl; //xxxx
	return 0;
}

 使用范围for访问对象中的元素
 需要特别注意的是:若是需要通过范围for修改对象的元素,则用于接收元素的变量e的类型必须是引用类型,否则e只是对象元素的拷贝,对e的修改不会影响到对象的元素。

 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");
	//使用范围for访问对象元素
	for (auto e : s)
	{
		cout << e;
	}
	cout << endl; //CSDN

	//使用范围for访问对象元素,并对其进行修改
	for (auto& e : s) //需要修改对象的元素,e必须是引用类型
	{
		e = 'x';
	}
	cout << s << endl; //xxxx
	return 0;
}

使用迭代器访问对象中的元素

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("CSDN");
	
	//使用迭代器访问对象元素
	string::iterator it1 = s.begin();
	while (it1 != s.end())
	{
		cout << *it1;
		it1++;
	}
	cout << endl; //CSDN

	//使用迭代器访问对象元素,并对其进行修改
	string::iterator it2 = s.begin();
	while (it2 != s.end())
	{
		*it2 += 1;
		it2++;
	}
	cout << s << endl; //DTEO
	return 0;
}

11.string与字符串之间的转换

c_str的使用

c_str函数返回字符串从\0结尾的字符串,但是c++中的字符串不一定以\0结尾,c++中字符串类以size为准来结尾,所以它叫:c_str,是c语言的规则。

int main()
{
string filename("test.cpp");
cout << filename << endl;
cout << filename.c_str() << endl;

filename += '\0';
filename += "string.cpp";
cout << filename << endl; // string 对象size为准--test.cppstring.cpp
cout << filename.c_str() << endl; // 常量字符串对象\0---test.cpp
}

 11.string中的getline函数

我们知道,使用>>进行输入操作时,当>>读取到空格便会停止读取,基于此,我们将不能用>>将一串含有空格的字符串读入到string对象中。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;
	cin >> s; //输入:hello CSDN
	cout << s << endl; //输出:hello
	return 0;
}

这时,我们就需要用getline函数完成一串含有空格的字符串的读取操作了。

(1)用法一

istream& getline (istream& is, string& str);

getline函数将从is中提取到的字符存储到str中,直到读取到换行符’\n’为止。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;
	getline(cin, s); //输入:hello CSDN
	cout << s << endl; //输出:hello CSDN
	return 0;
}

(2)用法二:

istream& getline (istream& is, string& str, char delim);

getline函数将从is中提取到的字符存储到str中,直到读取到分隔符delim或换行符’\n’为止。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;
	getline(cin, s, 'D'); //输入:hello CSDN
	cout << s << endl; //输出:hello CS
	return 0;
}

12. string中npos的使用

 用例:把字符串中的空格换成%%

int main()
{
	string s1("hello world hello bit");
	cout << s1 << endl;
	size_t i = s1.find(' ');
	while (i != string::npos)
	{
		s1.replace(i, 1, "%%");
		i = s1.find(' ', i+2);
	}

	cout << s1 << endl;
}

本篇博客到此结束,欢迎评论区留言~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值