前言
从本篇博客开始,就正式来介绍STL的正式内容,STL在C++中的学习中非常重要,具有举足轻重的地位,这块儿内容会给我们提供很多现成的接口,可以大大简化我们的代码,我们之前用C语言写的代码将会被极大地简化,所以如果你学习C++,那么请认真阅读下面的内容,下面进入正文。
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个字符的部分
上面展示了一些函数,这些都是STL库中已经实现好的函数,我们需要记住并会用这些函数,下面举一些例子帮助大家理解。
#include<iostream>
using namespace std;
void test1()
{
string s1;
cout << s1 << endl;
string s2("hello world");
cout << s2 << endl;
string s3("hello", 3);
cout << s3 << endl;
string s4(10, 'a');
cout << s4 << endl;
string s5(s2);
cout << s5 << endl;
string s6(s2, 0, 4);
cout << s6 << endl;
}
int main()
{
test1();
return 0;
}
hello world
hel
aaaaaaaaaa
hello world
hell
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 9164)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
大家可以看到,我们按照函数给的参数,可以实现一系列功能,这些都是string的定义方式。
2. string的插入
2.1 使用push_back进行尾插
函数模型
void push_back (char c);
#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;
}
CSDN
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 12256)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里大家看到代码应该很好理解,我们直接依次调用push_back函数就可以实现尾插。
2.2 使用insert插入
函数模型
string& insert (size_t pos, const string& str);
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
//insert(pos, str)在pos位置插入字符串str
s.insert(1, "S"); //CS
//insert(pos, string)在pos位置插入string对象
string t("D");
s.insert(2, t); //CSD
//insert(pos, char)在pos位置插入字符char
s.insert(s.end(), 'N'); //CSDN
s.insert(s.begin(), 'Y');//第三种迭代器用法,同上
s.insert(5, "OK");
cout << s << endl; //YCSDNOK
return 0;
}
YCSDNOK
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 2360)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里大家注意insert函数的3中用法,前两种是在指定位置插入字符(串)或者string对象,第三种迭代器用法大家需要注意,begin()代表起始位置,end()表示末尾位置的下一个位置,这种用法我们只能插入字符,不能是字符串,这个细节大家需要注意一下。
3. string的拼接
函数模型
string& append (const string& str);
string& append (const char* s);
string& append (size_t n, char 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;
}
I like C++!!!
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 11580)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
大家来看上面的代码,我们使用append函数实现了拼接功能,我们可以是两个string对象进行拼接,也可以是string对象与字符(串)拼接,还可以在末尾拼接指定数目的字符,这几种用法大家需要记住。
4. string的删除
4.1 使用pop_back尾删
函数模型
void 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;
}
C
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 17104)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
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 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;
}
I
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 25028)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里大家要注意erase的三种用法,我们可以一次删除多个字符,也可以删除指定位置的字符,还可以删除一段区间内的所有字符。
5. string的查找
5.1 使用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 (char c, size_t pos = 0) const;
这里需要为大家说明一下,参数中pos=0是指从0开始查询,我们调用函数的时候不用管它。
#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;
}
7
11
4
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 4092)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里大家通过例子,想必也很快可以理解find函数的用法,它返回的是一个正整数值,这个值其实大家可以理解为"下标",类比数组中的下标。
5.2 使用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 (char c, size_t pos = npos) const;
#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 str1[] = "reference";
size_t pos2 = s1.rfind(str1);
cout << pos2 << endl; //25
//rfind(char)反向搜索与字符char所匹配的第一个位置
size_t pos3 = s1.rfind('/');
cout << pos3 << endl; //53
return 0;
}
42
25
53
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 14316)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里的用法与上面是一样的,大家可以类比进行学习。
6. string的比较
函数模型
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;
比较规则:
1、比较字符串中第一个不匹配的字符值较小,或者所有比较字符都匹配,但比较字符串较短,则返回小于0的值。
2、比较字符串中第一个不匹配的字符值较大,或者所有比较字符都匹配,但比较字符串较长,则返回大于0的值。
3、比较的两个字符串相等,则返回0。
#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;
}
1
-1
0
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 22304)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
注意:除了支持string类之间进行比较,compare函数还支持string类和字符串进行比较。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello world");
char str1[] = "kpl";
char str2[] = "apl";
char str3[] = "hello world";
cout << s1.compare(str1) << endl; //-1
cout << s1.compare(str2) << endl; //1
cout << s1.compare(str3) << endl; //0
return 0;
}
-1
1
0
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 24016)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
7. string的替换
函数模型
string& replace (size_t pos, size_t len, const char* s);
string& replace (size_t pos, size_t len, size_t n, char c);
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("hello world");
//replace(pos, len, str)将pos位置开始的len个字符替换为字符串str
s.replace(6, 4, "CSDN"); //hello CSDNd
//replace(pos, len, n, char)将pos位置开始的len个字符替换为n个字符char
s.replace(10, 1, 3, '!'); //hello CSDN!!!
cout << s << endl;
return 0;
}
hello CSDN!!!
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 24756)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里我们使用replace函数完成替换的操作,两种替换方法都可以实现从指定位置开始替换。
8. string的交换
函数模型
void swap (string& x, string& y);
void swap (string& str);
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello");
string s2("CSDN");
//使用非成员函数swap交换s1和s2
swap(s1, s2);
cout << s1 << endl; //CSDN
cout << s2 << endl; //hello
//使用string类的成员函数swap交换s1和s2
s1.swap(s2);
cout << s1 << endl; //hello
cout << s2 << endl; //CSDN
return 0;
}
CSDN
hello
hello
CSDN
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 12256)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
9. string的容量和大小
9.1 使用size函数或length函数获取当前有效字符的个数
函数模型
size_t size() const;
size_t length() const;
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("CSDN");
cout << s.size() << endl; //4
cout << s.length() << endl; //4
return 0;
}
4
4
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 18556)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
9.2 使用max_size函数获取string对象最多可包含的字符数
函数模型
size_t max_size() const;
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
cout << s.max_size() << endl;
return 0;
}
9223372036854775807
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 11476)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里大家可以发现一个string对象可以包含非常多的字符。
9.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;
}
15
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 24248)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
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("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,这里大家注意,缩小的时候capacity是不变的
return 0;
}
CSDN
20
31
CSDNxxxxxxxxxxxxxxxx
20
31
CS
2
15
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 23180)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
9.5 使用reserve改变当前对象的容量大小
函数模型
void reserve (size_t n = 0);
reserve规则:
1、当n大于对象当前的capacity时,将capacity扩大到n或大于n。
2、当n小于对象当前的capacity时,什么也不做。
#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;
}
CSDN
4
15
CSDN
4
31
CSDN
4
31
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 9256)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
注意 :此函数对字符串的size没有影响,并且无法更改其内容。
9.6 使用clear删除对象的内容,删除后对象变为空字符串
函数模型
void clear();
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("CSDN");
//clear()删除对象的内容,该对象将变为空字符串
s.clear();
cout << s << endl; //空字符串
return 0;
}
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 1896)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
9.7 使用empty判断对象是否为空
函数模型
bool empty() const;
#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;
}
0
1
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 10944)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里大家根据代码运行的结果可以看到,是空字符串时返回1,否则返回0。
10. string中的元素访问
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("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;
}
CSDN
xxxx
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 14580)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
10.2 使用at访问对象中的元素
因为at函数也是使用的引用返回,所以我们也可以通过at函数修改对应位置的元素。
函数模型
char& at (size_t pos);
const char& at (size_t pos) const;
CSDN
xxxx
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 43572)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
10.3 使用范围for访问对象中的元素
需要特别注意的是:若是需要通过范围for修改对象的元素,则用于接收元素的变量e的类型必须是引用类型,否则e只是对象元素的拷贝,对e的修改不会影响到对象的元素。
这里大家来看两段代码,就可以理解上面的解释;
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("CSDN");
for (auto e : s)
{
cout << e;
}
cout << endl; //CSDN
for (auto e : s)
{
e = 'x';
}
cout << s << endl;
return 0;
}
大家先来看第一段代码,猜猜它的运行结果;
CSDN
CSDN
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 34408)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
大家会发现,两次打印的结果是一样的,这正是因为我们在想改变对象元素时没有使用引用类型,导致我们无法改变原对象的元素,这里大家可以类比于我们之前在C语言中学过的传值调用和传址调用,我们必须使用传址调用才可以实现形参改变导致实参改变。
#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;
}
我们改成上面这种写法,就可以实现我们期望的效果。
CSDN
xxxx
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 32688)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
10.4 使用迭代器访问对象中的元素
#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;
}
CSDN
DTEO
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 37648)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
大家注意,迭代器的用法是一种比较特殊的用法,这更像一种模板,我们可以记忆一下,后面我们学到其他容器也可以套用类似的方式。
11. string中运算符的使用
11.1 operator=
string类中对=运算符进行了重载,重载后的=运算符支持string类的赋值、字符串的赋值以及字符的赋值。
#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;
}
CSDN
hello
x
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 26856)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
11.2 operator+=
string类中对+=运算符进行了重载,重载后的+=运算符支持string类的复合赋值、字符串的复合赋值以及字符的复合赋值。
#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;
}
hello
hello CSDN
hello CSDN!
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 32420)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
11.3 operator+
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;
}
superman
superwoman
womansuper
super!
!super
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 34940)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
11.4 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;
}
这里就和我们前面学的C++的输入输出是一样的。
11.5 relational operators
string类中还对一系列关系运算符进行了重载,它们分别是==、!=、<、<=、>、>=。
重载后的关系运算符支持string类和string类之间的关系比较、string类和字符串之间的关系比较、字符串和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;
}
0
1
0
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 26812)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
注意:这些重载的关系比较运算符所比较的都是对应字符的ASCII码值。返回值是bool值。
12. string中与迭代器相关的函数
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;
}
hello string
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 38332)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里其实我们前面已经提到过了,我们使用迭代器也可以访问对象的元素。这里就是使用正向迭代器来访问string对象的例子。
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 string");
//反向迭代器
string::reverse_iterator rit = s.rbegin();
while (rit != s.rend())
{
cout << *rit;
rit++;
}
cout << endl; //gnirts olleh
return 0;
}
gnirts olleh
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 644)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这里大家看到输出的结果,刚好是反的,这就是反向迭代器的作用,其用法和正向迭代器基本是一样的,所以大家可以类比记忆。
13. string与字符串之间的转换
13.1 将字符串转换为string
将字符串转换为string很简单,在前面讲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;
}
hello world
hello world
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 37960)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
13.2 使用c_str或data将string转换为字符串
函数模型
const char* c_str() const;
const char* data() const;
#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;
}
hello world
hello world
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 31524)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
区别:
- 在C++98中,c_str()返回 const char* 类型,返回的字符串会以空字符结尾。
- 在C++98中,data()返回 const char* 类型,返回的字符串不以空字符结尾。
- 但是在C++11版本中,c_str()与data()用法相同。
14. string中子字符串的提取
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;
//substr(pos, n)提取pos位置开始的n个字符序列作为返回值
s2 = s1.substr(2, 4);
cout << s2 << endl; //cdef
return 0;
}
cdef
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 22772)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
14.2 使用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; //cdef
return 0;
}
cdef
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 29016)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
15. string中的getline函数
我们知道,使用>>进行输入操作时,当>>读取到空格便会停止读取,基于此,我们将不能用>>将一串含有空格的字符串读入到string对象中。
这时,我们就需要用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 string
cout << s << endl; //输出:hello string
return 0;
}
hello string
hello string
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 40392)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
用法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;
}
hello CSDN
hello CS
C:\code\test_c\test_10_18\x64\Debug\test_10_18.exe (进程 4616)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
这两种用法大家都需要熟悉,第一种用法就类似我们C语言中的scanf函数,输入什么就输出什么;而第二种用法,我们可以控制输出的内容。
16. 总结
本篇的内容到此就结束了,为大家介绍了比较重要的接口,文中提到的函数,大家都需要熟练掌握,并且熟悉这种学习的方式,以便于后面我们继续学习其他容器,最后,希望本篇博客可以为大家带来帮助,感谢阅读!