目录
2.9.6使用clear删除对象的内容,删除后对象变为空字符串
2.13.2使用c_str或data将string转换为字符串
2.14.1使用substr函数提取string中的子字符串
2.14.3使用copy函数将string的子字符串复制到字符数组中
1.STL简介
1.1什么是
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。
1.2STL的历史版本
原始版本:
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许 任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原 始版本一样做开源使用。 HP版本--所有STL实现版本的始祖。
P. J. 版本:
由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读 性比较低,符号命名比较怪异。
RW版本:
由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一 般。
SGI版本:
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可 移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们后面学习
STL要阅读部分源代码,主要参考的就是这个版本。
1.3STL的六大组件
1.4有用的网址
2.string类
2.1string的多种定义方式
string(); //构造一个空字符串
string(const char* s); //用C-string构造string类
string(const char* s, size_t n); //用C-string的前n个字符构造string类
string(size_t n, char c); //用n个c字符构造string类
string(const string& str); //拷贝构造
string(const string& str, size_t pos, size_t len = npos); //用从pos位置开始的长度为len的字串来构造string类
示例:
string s1;
string s2("hello world");
string s3("hello world", 3);
string s4(10, 'a');
string s5(s2);
string s6(s2, 0, 5);
2.2string的插入
2.2.1尾插(push_back)
函数:void push_back (char c);
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
s.push_back('X');
s.push_back('Y');
s.push_back('W');
s.push_back('L');
cout << s << endl; //XYWL
return 0;
}
2.2.2insert插入
函数:
string& insert (size_t pos, const string& str);//在pos位置插入string对象
string& insert (size_t pos, const char* s);//在pos位置插入字符串str
iterator insert (iterator p, char c);//在pos位置插入字符char
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("X"); //X
//insert(pos, string)在pos位置插入string对象
string l("Y");
s.insert(2, l); //XY
//insert(pos, str)在pos位置插入字符串str
s.insert(1, "W"); //XYW
//insert(pos, char)在pos位置插入字符char
s.insert(s.end(), 'L'); //XYWL
cout << s << endl; //XYWL
return 0;
}
2.3拼接(append)
函数:string& append (const string& str);//拼接string对象
string& append (const char* s);//拼接字符串strstring& append (size_t n, char c);拼接字符char
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("I");
string s2(" love");
s1.append(s2); //I love
s1.append(" HHR"); //I love HHR
s1.append(3, '!'); //I love HHR!!!
cout << s1 << endl; //I love HHR!!!
return 0;
}
2.4删除
2.4.1尾删(pop_back)
函数:void pop_back();
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL");
s.pop_back();
s.pop_back();
s.pop_back();
cout << s << endl; //X
return 0;
}
2.4.2使用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 love XYWL!!!");
//erase(pos, n)删除pos位置开始的n个字符
s.erase(11, 3); //I love XYWL
//erase(pos)删除pos位置的字符
s.erase(s.end()-1); //I love XYW
//erase(pos1, pos2)删除[pos1,pos2)上所有字符
s.erase(s.begin() + 1, s.end()); //I
cout << s << endl; //I
return 0;
}
2.5string的查找
查找分为正向和反向:
2.5.1使用find函数正向搜索
函数:size_t find (const string& str, size_t pos = 0) const;//搜索与string对象所匹配的第一个位置
size_t find (const char* s, size_t pos = 0) cons//搜索与字符串str所匹配的第一个位置
size_t find (char c, size_t pos = 0) const;//搜索与字符char所匹配的第一个位置
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("https://www.acwing.com/problem/content/submission/1/");
string s2("www");
size_t pos1 = s1.find(s2);
cout << pos1 << endl; //8
char str[] = "acwing.com";
size_t pos2 = s1.find(str);
cout << pos2 << endl; //12
size_t pos3 = s1.find(':');
cout << pos3 << endl; //5
return 0;
}
2.5.2使用rfind函数反向搜索第一个匹配项
函数:size_t rfind (const string& str, size_t pos = npos) const;搜索与string对象所匹配的第一个位置
size_t rfind (const char* s, size_t pos = npos) const;//搜索与字符串str所匹配的第一个位置
size_t rfind (char c, size_t pos = npos) const;//搜索与字符char所匹配的第一个位置
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("https://www.acwing.com/problem/content/submission/1/");
string s2("1");
size_t pos1 = s1.rfind(s2);
cout << pos1 << endl; //50
char str[] = "content";
size_t pos2 = s1.rfind(str);
cout << pos2 << endl; //31
size_t pos3 = s1.rfind('/');
cout << pos3 << endl; //51
return 0;
}
特别注明:如果找不到则返回 string::npos
2.6string的比较
函数: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;//雷同
比较规则(同C语言):
1、比较字符串中第一个不匹配的字符值较小,或者所有比较字符都匹配,但比较字符串较短,则返回小于0的值。
2、比较字符串中第一个不匹配的字符值较大,或者所有比较字符都匹配,但比较字符串较长,则返回大于0的值。
3、比较的两个字符串相等,则返回0。总结:括号外的大为1,小-1,同0。
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello world");
string s2("hello hhy");
//"hello world"和"hello hhy"比较
cout << s1.compare(s2) << endl; //1
//"ello"和"hello hhy"比较
cout << s1.compare(1, 4, s2) << endl; //-1
//"hello"和"hello"比较
cout << s1.compare(0, 4, s2, 0, 4) << endl; //0
return 0;
}
2.7string的替换
函数:string& replace (size_t pos, size_t len, const char* s);//将pos位置开始的len个字符替换为字符串str
string& replace (size_t pos, size_t len, size_t n, char c);将pos位置开始的len个字符替换为n个字符char
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("hello world");
s.replace(6, 4, "XTWL"); //hello XYWLd
//replace(pos, len, n, char)将pos位置开始的len个字符替换为n个字符char
s.replace(10, 1, 1, '!'); //hello XYWL!
cout << s << endl;
return 0;
}
2.8string的交换
函数:void swap (string& x, string& y);
void swap (string& str);
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello");
string s2("world");
swap(s1, s2);
cout << s1 << endl; //world
cout << s2 << endl; //hello
s1.swap(s2);
cout << s1 << endl; //hello
cout << s2 << endl; //world
return 0;
}
2.9string的大小及容量
2.9.1获取有效字符的个数
函数:size_t size() const;
size_t length() const;
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL");
cout << s.size() << endl; //4
cout << s.length() << endl; //4
return 0;
}
2.9.3使用capacity函数获取所分配的空间的大小
函数:size_t capacity() const;
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL);
cout << s.capacity() << endl; //15
return 0;
}
2.9.4使用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。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("XYWL");
s1.resize(20);
cout << s1 << endl; //XYWL
cout << s1.size() << endl; //20
cout << s1.capacity() << endl; //31
string s2("XYWL");
s2.resize(20, '0');
cout << s2 << endl; //XYWL0000000000000000
cout << s2.size() << endl; //20
cout << s2.capacity() << endl; //31
string s3("XYWL");
s3.resize(2);
cout << s3 << endl; //XY
cout << s3.size() << endl; //2
cout << s3.capacity() << endl; //15
return 0;
}
注意: 若给出的n大于当前对象的capacity,则capacity也会随其增长。
2.9.5用reserve改变当前对象容量的大小
函数:void reserve (size_t n = 0);
reserve规则:
1、当n大于对象当前的capacity时,将capacity扩大到n或大于n。
2、当n小于对象当前的capacity时,什么也不做(与resize不同)。
示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL");
cout << s << endl; //XYWL
cout << s.size() << endl; //4
cout << s.capacity() << endl; //15
s.reserve(30);
cout << s << endl; //XYWL
cout << s.size() << endl; //4
cout << s.capacity() << endl; //31
s.reserve(3);
cout << s << endl; //XYWL
cout << s.size() << endl; //4
cout << s.capacity() << endl; //31
return 0;
}
注:此函数对size没任何影响
2.9.6使用clear删除对象的内容,删除后对象变为空字符串
函数:void clear();
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL");
//clear()删除对象的内容,该对象将变为空字符串
s.clear();
cout << s << endl; //空字符串
return 0;
}
2.9.7使用empty判断对象是否为空
函数:bool empty() const;
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL");
cout << s.empty() << endl; //0
s.clear();
cout << s.empty() << endl; //1
return 0;
}
2.10string中元素的多种访问方式
2.10.1下标
在string中我们可以直接使用[ ]+下标访问对象中的元素。
函数:char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL");
//[]+下标访问对象元素
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;
}
2.10.2使用at访问对象中的元素
函数:char& at (size_t pos);
const char& at (size_t pos) const;
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL");
for (size_t i = 0; i < s.size(); i++)
{
cout << s.at(i);
}
cout << endl;
for (size_t i = 0; i < s.size(); i++)
{
s.at(i) = 'x';
}
cout << s << endl; //xxxx
return 0;
}
2.10.3使用范围for访问对象中的元素
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL");
for (auto e : s)
{
cout << e;
}
cout << endl; //XYWL
for (auto& e : s)
{
e = 'x';
}
cout << s << endl; //xxxx
return 0;
}
2.10.4使用迭代器访问对象中的元素
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("XYWL");
string::iterator it1 = s.begin();
while (it1 != s.end())
{
cout << *it1;
it1++;
}
cout << endl; //XYWL
string::iterator it2 = s.begin();
while (it2 != s.end())
{
*it2 += 1;
it2++;
}
cout << s << endl; //YZXM
return 0;
}
2.11string中的运算符
2.11.1=
string类中对=运算符进行了重载,重载后的=运算符支持string类的赋值、字符串的赋值以及字符的赋值。
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1;
string s2("XYWL");
s1 = s2;
cout << s1 << endl; //XYWL
s1 = "hello";
cout << s1 << endl; //hello
s1 = '0';
cout << s1 << endl; //0
return 0;
}
2.11.2+=
string类中对+=运算符进行了重载,重载后的+=运算符支持string类的复合赋值、字符串的复合赋值以及字符复合的赋值。
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1;
string s2("hello");
//支持string类的复合赋值
s1 += s2;
cout << s1 << endl; //hello
//支持字符串的复合赋值
s1 += " XYWL";
cout << s1 << endl; //hello XYWL
//支持字符的复合赋值
s1 += '!';
cout << s1 << endl; //hello XYWL!
return 0;
}
2.11.3+
string类中对+运算符进行了重载,重载后的+运算符支持以下几种类型的操作:
string类 + string类
string类 + 字符串
字符串 + string类
string类 + 字符
字符 + string类
它们相加后均返回一个string类对象。
示例:
#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;
}
2.11.4operator>> 和 operator<<
函数: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;
}
2.11.5relational operators
string类中还对一系列关系运算符进行了重载,它们分别是==、!=、<、<=、>、>=。
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("abcd");
string s2("abde");
cout << (s1 > s2) << endl; //0
cout << (s1 < s2) << endl; //1
cout << (s1 == s2) << endl; //0
return 0;
}
注:比较的是ASCII码
2.12string中与迭代器相关的函数
2.12.1与正向迭代器相关的函数
begin函数:返回一个指向字符串第一个字符的迭代器。
函数:iterator begin();
const_iterator begin() const;
end函数:返回一个指向字符串结束字符的迭代器,即’\0’。
函数: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.12.2与反向迭代器相关的函数
rbegin函数:返回指向字符串最后一个字符的反向迭代器。
函数:reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
rend函数:返回指向字符串第一个字符前面的理论元素的反向迭代器。
函数:reverse_iterator rend();
const_reverse_iterator rend() const;
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("hello world");
string::reverse_iterator rit = s.rbegin();
while (rit != s.rend())
{
cout << *rit;
rit++;
}
cout << endl; //dlrow olleh
return 0;
}
2.13string与字符串之间的转换
2.13.1将字符串转换为string
#include <iostream>
#include <string>
using namespace std;
int main()
{
//方式一
string s1("hello world");
//方式二
char str[] = "hello world";
string s2(str);
cout << s1 << endl; //hello world
cout << s2 << endl; //hello world
return 0;
}
2.13.2使用c_str或data将string转换为字符串
函数:const char* c_str() const;
const char* data() const;
区别:
1.在C++98中,c_str()返回 const char* 类型,返回的字符串会以空字符结尾。
2.在C++98中,data()返回 const char* 类型,返回的字符串不以空字符结尾。
3.但是在C++11版本中,c_str()与data()用法相同。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("hello world ");
const char* str1 = s.data();
const char* str2 = s.c_str();
cout << str1 << endl;
cout << str2 << endl;
return 0;
}
2.14string中子字符串的提取
2.14.1使用substr函数提取string中的子字符串
函数:string substr (size_t pos = 0, size_t len = npos) const;
示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("abcdef");
string s2;
s2 = s1.substr(2, 4);
cout << s2 << endl; //cdef
return 0;
}
2.14.3使用copy函数将string的子字符串复制到字符数组中
函数:size_t copy (char* s, size_t len, size_t pos = 0) const;
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("abcdef");
char str[20];
//copy(str, n, pos)复制pos位置开始的n个字符到str字符串
size_t length = s.copy(str, 4, 2);
//copy函数不会在复制内容的末尾附加'\0',需要手动加
str[length] = '\0';
cout << str << endl; //dcef
return 0;
}
2.15string中的getline函数
因为在之前我们知道在读入字符串是时,cin>>当读到空格时就会停止,于是我们有了getline。
2.15.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.15.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, 'r'); //输入:hello world
cout << s << endl; //输出:hello wo
return 0;
}