【c++进阶(一)】STL之string接口介绍

💓博主CSDN主页:Am心若依旧💓

⏩专栏分类c++从入门到精通
🚚代码仓库:青酒余成🚚

🌹关注我🫵带你学习更多c++
  🔝🔝

1.前言

本章重点

本章着重讲解string中一些重要的接口函数:构造函数,析构函数,拷贝构造函数,赋值重载函数,插入,删除,扩容,resize,append等接口。

2. 构造函数和拷贝构造函数

重要接口:

//构造函数
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个字符的部分

示例:

void Teststring()
{

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);                 //用C格式字符串构造string类对象s5
string s6(s2, 0, 4);           //复制s2中从字符位置0开始并跨越4个字符的部分
}

3.string类对象的容量操作

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

size_t size() const;
size_t length() const;

示例:

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

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

size_t max_size() const;

示例:

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

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

size_t capacity() const;(重点)

示例:

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

注意:这里的capacity是指开辟的空间的大小,例如你有20块钱,但是你只用了5块钱。这里20就可以表示为开辟的空间大小,5表示为你已经用掉的空间大小

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

void resize (size_t n);
void resize (size_t n, char c);

对上述进行解释:将字符串的长度调整为 n 个字符。

1.如果 n 小于当前字符串长度(已经使用的长度),则当前值将缩短为前 n 个字符,并删除第 n 个字符以外的字符。

2.如果 n 大于当前字符串长度,则通过在末尾插入尽可能多的字符来扩展当前内容,以达到 n 的大小。如果指定了 c,则新元素将初始化为 c ,否则,它们是值初始化字符(空字符)

 示例:

#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;
}

这里不需要担心是否会超出容量的大小,在resize里面内置了扩容的函数,一旦超过了当前容量会先扩容,然后再进行初始化

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

void reserve (size_t n = 0);

#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;
}

注意:capacity的含义是不管容量怎么扩大,他都不会影响实际有效的元素个数。 而上面所说的resize是,他会实际影响有效的元素个数。并且如果resize在减少有效元素的个数时,空间的大小即capacity的大小不会发生改变。

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

void clear();

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

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

ps:clear()只是将string有效字符清空,不改变底层空间大小。  

7、使用empty判断对象是否为空

bool empty() const;

 这里只需要比较容量和size的大小即可,有效元素的个数为0时,那就是空。

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

1、[ ]+下标来访问元素

  char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("string a");
	//[]+下标访问对象元素
	for (size_t i = 0; i < s.size(); i++)
	{
		cout << s[i];
	}
	cout << endl;

	return 0;
}

打印出来的是:string a

2、使用范围for访问对象中的元素

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

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

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

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

#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;
}

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

还不知道什么是迭代器的小伙伴推荐先阅读下面文章:

C++迭代器(STL迭代器)iterator详解-CSDN博客

C++ 迭代器 iterator 详解_c++ iterator-CSDN博客

1、与正向迭代器相关的函数

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

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

 iterator begin();
 const_iterator begin() const;

  iterator end();
 const_iterator end() const;

使用示例:

#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;
}

2、与反向迭代器相关的函数

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

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

        reverse_iterator rbegin();
 const_reverse_iterator rbegin() const;

        reverse_iterator rend();
 const_reverse_iterator rend() const;

使用示例:

#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;
}

6.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这个函数接口

接口一:

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;
}

接口二:

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;
}

7.string中的插入、删除、追加等相关函数

1.push_back进行尾插

void push_back (char c);

2.使用insert进行插入

string& insert (size_t pos, const string& str);
string& insert (size_t pos,   size_t n, char c)
iterator insert (iterator p, char c);

解释:在pos位置插入一个字符串str;在pos位置插入一个n个字符c;在迭代器位置插入字符c

示例:

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

	//insert(pos, str)在pos位置插入字符串str
	s.insert(1, "S"); //CS

	//insert(pos,n,c)在pos位置插入n个c字符
	char c='S';
	s.insert(2,3 ,t); //CSSSS

	//insert(pos, char)在pos位置插入字符char
	s.insert(s.end(), 'N'); //CSDN
	
	cout << s << endl; //CSDN
	return 0;
}

3.append相关接口

 string& append (const string& str);
string& append (const char* s);
string& append (size_t n, char c);

解释:有一个对象s1后,把str追加到s1后面;把s追加到s1后面;在s1后面追加n个字符c

示例:

#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.pop_back接口进行尾删

void pop_back();

5.使用erase来进行删除

string& erase (size_t pos = 0, size_t len = npos);
iterator erase (iterator p);
iterator erase (iterator first, iterator last);

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("I like C++!!!");
    //这里面的npos可以把他当成无穷值,不显示给定,就表示从pos开始后面的全部删除
	//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;
}

8.总结

 string这个类非常的重要,基本可以说string可以贯穿程序员的始终,你无时无刻不在处理字符串,你也无时无刻不在使用字符串。因此一定要好好的掌握string中的重要接口。

string中的重要接口除了上述常用的以外,还有许多需要特别关注的,各位看官老爷可以自己去看看。链接string - C++ Reference

find函数接口

operator+=函数接口

c_str函数接口

operator<<和operator>>输入输出运算符重载函数接口

 

                                        下期预告:string类的模拟实现 

相关推荐

  1. C++——STL

    2024-06-05 20:18:03       12 阅读
  2. C++编程 --- 2.初始STL

    2024-06-05 20:18:03       15 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-05 20:18:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-05 20:18:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-05 20:18:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-05 20:18:03       18 阅读

热门阅读

  1. 封装PHP用于发送GET和POST请求的公共方法

    2024-06-05 20:18:03       10 阅读
  2. Elasticsearch 认证模拟题 - 6

    2024-06-05 20:18:03       7 阅读
  3. Elasticsearch (ES)内存管理降低内存占用率

    2024-06-05 20:18:03       7 阅读
  4. 高通Android 12/13实现USB拔出关机功能

    2024-06-05 20:18:03       7 阅读
  5. git命令

    git命令

    2024-06-05 20:18:03      7 阅读