当前位置: 首页 > news >正文

C++:STL简介和容器string用法篇

一、STL简介

       STL是C++中的标准模板库(Standard Template Library)的缩写。它是C++标准库的一部分,提供了一系列的数据结构和算法模板,包括各种容器、算法、迭代器、仿函数等,用于简化和加速C++程序的开发过程。STL的设计理念是提供通用、高效的数据结构和算法实现,使得开发者可以更加专注于业务逻辑的实现,提高代码的可读性、可维护性和可移植性。

       STL在C++中有以下几个主要用处:

  1. 提供丰富的数据结构:STL包含了各种常用的容器,如动态数组(vector)、双向链表(list)、映射(map)、集合(set)等。这些数据结构可以满足不同的需求,如存储数据、快速查找、有序存储等。

  2. 实现高效的算法:STL提供了大量的算法模板,包括排序、查找、变换、合并等,这些算法经过了优化和测试,通常具有高效的执行速度和可靠的性能。开发者可以直接使用这些算法,无需自己从头实现,提高了开发效率。

  3. 提供灵活的迭代器:STL中的迭代器提供了一种统一的访问数据结构元素的方式,包括输入迭代器、输出迭代器、正向迭代器、双向迭代器和随机访问迭代器等。开发者可以根据需要选择合适的迭代器类型进行数据遍历和操作。

  4. 支持泛型编程:STL是基于模板的,支持泛型编程。这意味着开发者可以编写通用的代码,适用于不同类型的数据结构和数据类型,提高了代码的复用性和通用性。

  5. 提高代码的可读性和可维护性:STL提供了经过优化和测试的标准化实现,使得代码更加清晰易懂。开发者可以直接使用STL提供的功能模块,避免了重复造轮子的工作,同时也降低了出错的风险,提高了代码的可维护性和可读性。

       综上所述,STL在提高开发效率和代码质量等方面具有很大的作用,是C++程序开发中不可或缺的重要工具。

       STL六大组件:

       网上有句话说:“不懂STL,不要说你会C++”。STL是C++中的优秀作品,有了它的陪伴,许多底层的数据结构以及算法都不需要自己重新造轮子,使我们能够快速地进行开发。

       我们的STL系列将从容器string部分开始介绍。

二、string类

       标准库类型string表示可变长的字符序列,使用string类型必须首先包含string头文件。作为标准库的一部分,string定义在命名空间std中。

1.定义和初始化string对象

       string是一个类,因此,实例化出string类时,会调用该类的构造函数。string对象也可以使用其他方式来初始化。常用的string对象构造方法有以下几种:

string s1;// 调用默认构造函数,s1是一个空字符串
string s2 = s1;// 调用拷贝构造函数
string s3 = "hello world!"; // 使用字符串初始化s3
string s4(10, 's'); // 使用10个's'字符初始化s4
string s5(s3, 6, 3);// 从第七个字符开始,将3个s3字符串中的字符拷贝到s5中
string s6(s3, 3);// 将前3个s3字符串中的字符拷贝到s6中

       在构造s5的过程中,可以不传第三个参数,那么编译器将会将第三个参数设为string::npos,而string::npos的值为大约42亿,也就是说,编译器会将s3中的从第七个字符开始,拷贝42亿个字符给s5,但是s3显然没有那么多字符。所以当遇到s3字符串的结尾时,编译器将会停止拷贝。那如果第三个参数传的过大,拷贝长度大于从开始到结尾的长度,那也是遇到字符串末尾然后停止拷贝。

       string类中重载了流插入<<、流提取>>操作符,使我们可以像打印、输入int型、char型等内置类型一样打印或输入string型。也重载了内置类型常用的大多数操作符。

2.遍历string对象

       string类中重载了'[]'运算符,使我们可以像遍历字符数组一样遍历string对象。

void test1()// string对象的遍历
{string s1("hello world!");for (int i = 0; i < s1.size(); i++){cout << s1[i] << ' ';}
}int main()
{test1();return 0;
}

       运行程序,结果如下:

       也可以将上面的循环换为范围for循环来遍历string对象,使用起来更加方便。

三、string类成员函数

1.容量

(1)size和length

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

       string类中有求字符串长度的函数size()和length(),它们的作用相同。调用方法如下:

void test1()
{string s1("hello world!");string s2("hellohello world!");cout << s1.size() <<endl;cout << s2.length();
}

       运行程序,结果如下:

(2)max_size

       string类中的max_size()函数用于求字符串的潜在最大长度。

size_t max_size() const;

       调用该函数之后,会得到一个非常大的数字。

(3)resize

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

       string类中提供了两个调节字符串大小的函数。第一个参数都是一个无符号整形,意思是将字符串大小调整为n。若字符串长度大于n,那么n之后的字符将会丢弃,若字符串的长度小于n,那么第一个函数将会在n之后填充空字符,第二个函数则会使用指定的字符填充。

       我们知道,字符串末尾还隐藏了一个‘\0’字符。空字符是不计入长度的。计算字符串长度时,遇到任意空字符就停止计数。打印的时候也是以任意空字符为结尾的。

void test1()
{string s1("hello\0\0\0\0\0 world!    ");string s2("hellohello world!");//s1.resize(18);cout << s1 << 'a' << endl;cout << s1.size() << endl;}

       运行程序,结果如下:

       但是我们将resize函数取消注释,再次运行程序:

       发现长度来到了18,也就是说,编译器填充的空字符,是计入长度的。

       通过监视窗口我们看到,没有执行resize语句时,s1中字符串只有五个字符,执行之后,后面13个字符都是\0并且计入长度。

(4)capacity

size_t capacity() const;

       string类中有计算容量的成员函数,它表示编译器为对象实际分配的内存空间,它可以大于或等于字符串的长度。若容量满时,会自动扩容。

(5)reverse

void reserve (size_t n = 0);

       reverse函数使用来修改字符串容量的。给reverse传的参数n是告诉编译器假定字符串的长度为n,然后让编译器重新为对象分配空间。编译器会结合实际字符串长度来分配空间。若n小于实际字符串长度,容量的变化具体看编译器。

(6)clear

void clear();

       它的作用为清空字符串。使对象变为长度为0的字符串。

(7)empty

bool empty() const;

       它的作用是判断字符串是否为空,并不会改变字符串中的内容。

(8)shrink_to_fit

bool empty() const;

       请求字符串减小其容量以适应其大小。

2.元素访问

(1)operator[]

       string类中具有运算符重载, 使我们可以像访问数组那样访问string对象中的值。

char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

(2)at

char& at (size_t pos);
const char& at (size_t pos) const;

       返回对字符串中位置pos处的字符的引用。

(3)back

char& back();
const char& back() const;

       返回对字符串最后一个字符的引用。此函数不应在空字符串上调用。

(4)front

char& front();
const char& front() const;

       返回对字符串第一个字符的引用。此函数不应在空字符串上调用。

3.修改

(1)operator+=

string& operator+= (const string& str);
string& operator+= (const char* s);
string& operator+= (char c);

       string具有+=重载函数,使我们可以像内置类型一样使用+=操作符:

void test1()
{string s1("hello world!");string s2("hi");s1 += "sss";s1 += 'a';s1 += s2;cout << s1 << endl;cout << s1.size() << endl;
}

       运行代码,结果如图所示:

       有了+=重载操作符重载,我们可以很方便地为字符串后添加字符。

(2)append

string& append (const string& str);
string& append (const string& str, size_t subpos, size_t sublen);
string& append (const char* s);
string& append (const char* s, size_t n);
string& append (size_t n, char c);
template <class InputIterator>
string& append (InputIterator first, InputIterator last);

       append也表示向字符串的末尾添加字符串。它重载了许多函数,实现了很多功能。

string& append (const string& str);

       表示向一个string对象末尾添加另一个string对象,也就是在一个字符串的末尾添加另一串字符串。

string& append (const string& str, size_t subpos, size_t sublen);

       表示向一个string对象末尾添加另一个string对象的一部分,它从subpos位置开始,直到拷贝长度达到sublen时为止或者直到遇到字符串末尾。

string& append (const char* s);

       表示向string对象末尾附加一个由指针变量指向的字符串。

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

       表示向string对象末尾附加一个由指针变量指向的字符串的前n个字符。

string& append (size_t n, char c);

       表示向string对象末尾附加n个c字符。

(3)push_back

void push_back (char c);

       表示向string对象末尾附加1个c字符。

(4)assign

string& assign (const string& str);
string& assign (const string& str, size_t subpos, size_t sublen);
string& assign (const char* s);
string& assign (const char* s, size_t n);
string& assign (size_t n, char c);

        assign表示赋值,将当前值清空并赋新值。

string& assign (const string& str);

       表示将另一个string对象赋给当前string对象。

string& assign (const string& str, size_t subpos, size_t sublen);

       表示将另一个string对象的一部分赋给当前string对象。从subpos开始,到sublen处结束,或遇到字符串尾结束。

string& assign (const char* s);

       表示将s指向的字符串赋给当前string对象。

string& assign (const char* s, size_t n);

        表示将s指向的字符串的前n个字符赋给当前string对象。

string& assign (size_t n, char c);

       表示将n个c字符赋给当前string对象。

(5)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);string& insert (size_t pos, const char* s, size_t n);string& insert (size_t pos, size_t n, char c);
void insert (iterator p, size_t n, char c);

        insert也表示插入,它支持在任意位置插入。不过它的效率不高。

string& insert (size_t pos, const string& str);

       表示在下标pos之后插入一个string对象。

string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);

       表示在下标pos之后插入一个string对象的一部分,它从subpos处开始,直到拷贝长度达到sublen或者遇到字符串结尾。

string& insert (size_t pos, const char* s);

       表示在pos位置插入一个s指向的字符串。

string& insert (size_t pos, const char* s, size_t n);

       表示在pos位置插入一个s指向的字符串的前n个字符。

string& insert (size_t pos, size_t n, char c);

        表示在pos位置插入n个字符c。

(6)erase

string& erase (size_t pos = 0, size_t len = npos);

       erase表示删除,删除从pos位置开始, 直到删除长度达到len或者对象中已经无字符。若不传参数,那么表示全部删除。

(7)replace

string& replace (size_t pos,  size_t len,  const string& str);
string& replace (size_t pos,  size_t len,  const string& str,size_t subpos, size_t sublen);
string& replace (size_t pos,  size_t len,  const char* s);
string& replace (size_t pos,  size_t len,  const char* s, size_t n);
string& replace (size_t pos,  size_t len,  size_t n, char c);

       replace表示替换。

string& replace (size_t pos,  size_t len,  const string& str);

       表示从下标pos位置开始,len长度的字符替换为另一个string对象中的字符串。

string& replace (size_t pos,  size_t len,  const string& str,size_t subpos, size_t sublen);

       表示从下标pos位置开始,len长度的字符替换为另一个string对象中的字符串的一部分,从小标subpos位置开始,拷贝sublen长度的字符串或遇到字符串末尾。

string& replace (size_t pos,  size_t len,  const char* s);

       表示从下标pos位置开始,len长度的字符替换为s指向的字符串。

string& replace (size_t pos,  size_t len,  const char* s, size_t n);

       表示从下标pos位置开始,len长度的字符替换为s指向的字符串的前n个字符。

string& replace (size_t pos,  size_t len,  size_t n, char c);

       表示从下标pos位置开始,len长度的字符替换为n个c字符。

(8)swap

void swap (string& str);
void swap (string& x, string& y);

       交换两string对象的值。

void test1()
{string s1("hello world!");string s2("abcdefg");s1.swap(s2);cout << s1 << endl;cout << s2 << endl;
}

       运行代码,结果如下图所示:

(9)pop_back

void pop_back();

       尾部删除一个字符。

(10)getline

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

       从流中提取一行字符串到string对象中,直到遇到delim(界定字符)或换行符。若指定了界定字符,那么当输入界定字符之后,编译器会只保留界定字符之前的字符,将string对象存储的值删除,并添加上新输入的字符。若没有指定界定字符,那么当遇到换行符时,即代表输入结束。

4.字符串操作

(1)c_str

const char* c_str() const;

       返回一个字符串指针,指向一块存储着C风格字符串的空间。字符串的末尾附加了一个空字符。

(2)data

const char* data() const;

       返回一个字符串指针,指向一块存储着C风格字符串的空间。在C++11之前,该字符串末尾不附加空字符,C++11之后,附加了一个空字符,执行与c_str一样的操作。

(3)copy

size_t copy (char* s, size_t len, size_t pos = 0) const;

       从pos位置开始,拷贝len个长度的字符到s指向的空间中。返回拷贝字符的个数。

(4)find

size_t find (const string& str, size_t pos = 0) const;
size_t find (const char* s, size_t pos = 0) const;
size_t find (const char* s, size_t pos, size_type n) const;
size_t find (char c, size_t pos = 0) const;

       第一个重载成员函数可以查找子字符串,pos是开始查找的位置。若找到则返回子字符串在字符串中的下标,若找不到则返回nops。

       第二个重载成员函数可以查找s指向的字符串。

       第三个重载成员函数可以查找s指向的字符串,第三个参数n是查找的长度,若小于被查找的字符串长度,则查找前n个字符组成的字符串。

       第四个重载成员函数可以查找指定的字符。

(5)rfind

size_t rfind (const string& str, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos, size_t n) const;
size_t rfind (char c, size_t pos = npos) const;

       查找要查找的对象最后一次出现的位置。

(6)find_first_of

size_t find_first_of (const string& str, size_t pos = 0) const;
size_t find_first_of (const char* s, size_t pos = 0) const;
size_t find_first_of (const char* s, size_t pos, size_t n) const;
size_t find_first_of (char c, size_t pos = 0) const;

       在string对象中查找一个字符,它同时出现在另一个对象中并且在string对象中是第一个这样的字符。返回该字符的下标。支持查找另一个string对象、指针指向的空间,单个字符。

size_t find_last_of (const string& str, size_t pos = npos) const;
size_t find_last_of (const char* s, size_t pos = npos) const;
size_t find_last_of (const char* s, size_t pos, size_t n) const;
size_t find_last_of (char c, size_t pos = npos) const;

       在string对象中查找一个字符,它同时出现在另一个对象中并且在string对象中是最后一个这样的字符。

(7)find_first_not_of

size_t find_first_not_of (const string& str, size_t pos = 0) const;
size_t find_first_not_of (const char* s, size_t pos = 0) const;
size_t find_first_not_of (const char* s, size_t pos, size_t n) const;
size_t find_first_not_of (char c, size_t pos = 0) const;

       在string对象中查找一个字符,它在另一个对象中不存在,并且是第一个这样的字符,返回该字符的下标。

(8)find_last_not_of

size_t find_last_not_of (const string& str, size_t pos = npos) const;
size_t find_last_not_of (const char* s, size_t pos = npos) const;
size_t find_last_not_of (const char* s, size_t pos, size_t n) const;
size_t find_last_not_of (char c, size_t pos = npos) const;

       在string对象中查找一个字符,它在另一个对象中不存在,并且是最后一个这样的字符,返回该字符的下标。

(9)substr

string substr (size_t pos = 0, size_t len = npos) const;

       创建一个子字符串,该子字符串的值为string对象中从pos位置开始,len个长度或到达字符串末尾的字符串的拷贝。

(10)compare

int compare (const string& str) const;
int compare (size_t pos, size_t len, const string& str) const;
int compare (size_t pos, size_t len, const string& str,size_t subpos, size_t sublen) const;
int compare (const char* s) const;
int compare (size_t pos, size_t len, const char* s) const;
int compare (size_t pos, size_t len, const char* s, size_t n) const;

       将字符串的值与参数指定的字符串的值进行比较。

       返回值:

  • =0,两字符串相等。
  • >0,string对象1>string对象2。若遇到第一个字符串与第二个字符串不相等的第一个字符,比较它们的ascii值。
  • <0,string对象1<string对象2。
int compare (size_t pos, size_t len, const string& str) const;

       将string对象中从pos位置开始,len个长度的字符串与另一个对象比较。

int compare (size_t pos, size_t len, const string& str,size_t subpos, size_t sublen) const;

       将string对象中从pos位置开始,len个长度的字符串与另一个对象中的subpos位置开始,sublen长度的字符串比较。

相关文章:

  • Java中的序列化
  • 科林Linux6_网络
  • 机器人物理引擎
  • Slash后台管理系统源码阅读笔记 后面面板中的折线图统计卡片是怎么实现的?
  • Linux 基本使用和 web 程序部署云端
  • 【Linux】Ubuntu系统挂载NAS文件夹
  • 问题排查复盘
  • C++第十九弹---string模拟实现(下)
  • Python语法(全)
  • 南京观海微电子----升压和降压模块电路解析
  • web及网络基础图文详解
  • 内网渗透(不出网上线CS)
  • HCIP-Datacom-ARST自选题库__BGP/MPLS IP VPN单选【21道题】
  • 【教程】Linux部署Android安卓模拟器
  • 蓝桥杯练习系统(算法训练)ALGO-934 序列
  • CentOS7 安装JDK
  • chrome扩展demo1-小时钟
  • CSS 专业技巧
  • download使用浅析
  • JS专题之继承
  • MQ框架的比较
  • PHP变量
  • SOFAMosn配置模型
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 初识 webpack
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 深入浏览器事件循环的本质
  • 实现菜单下拉伸展折叠效果demo
  • 为什么要用IPython/Jupyter?
  • 正则学习笔记
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​比特币大跌的 2 个原因
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #Linux(Source Insight安装及工程建立)
  • #vue3 实现前端下载excel文件模板功能
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • $NOIp2018$劝退记
  • (C)一些题4
  • (LeetCode) T14. Longest Common Prefix
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (rabbitmq的高级特性)消息可靠性
  • (编译到47%失败)to be deleted
  • (四)js前端开发中设计模式之工厂方法模式
  • (一)基于IDEA的JAVA基础12
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)linux下的时间函数使用
  • (转)树状数组
  • (转)详解PHP处理密码的几种方式
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .FileZilla的使用和主动模式被动模式介绍
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .NET Framework与.NET Framework SDK有什么不同?