在实际开发中会经常使用字符串,所谓的字符串就是指一连串的字符,它由许多单个字符连接而成。字符串中可以包含任意任意字符,这些字符必须包含在一对英文双引号( " " )之内,例如"abc"。C++中定义了String类来封装字符串,并提供了一系列操作字符串的方法,它们都位于<string>头文件中。
我们先来看一下https://legacy.cplusplus.com/网站对string类的文档介绍:string类文档
总结如下:
string是表示字符串的字符串类
该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
string在底层实际是:basic_string模板类的别名,即:
typedef basic_string<char, char_traits, allocator>string;
不能操作多字节或者变长字符的序列。
在使用string类时,必须包含#include头文件以及using namespace std;
如下,C++98标准中对于string类实现了7个重载的构造函数:string类查询文档
其参数解析如下:
接下来我们演示使用如下四种常见的string类构造函数: 函数名称功能说明string()构造空的string类对象,即空字符串string(const char* s)用C-string来构造string类对象string(size_t n,char c)string类对象中包含n个字符cstring(const string&s)拷贝构造函数
如下代码,分别按上述构造函数顺序调用了相应构造函数初始化了4个string类对象:
#include<iostream>
#include<string>
using namespace std;
int main()
{
//构造空的string类对象,即空字符串
string s1;
//用C-string来构造string类对象
string s2("hello world");
//string类对象中包含n个字符c
string s3(5, 'x');
//拷贝构造函数
string s4(s2);
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
return 0;
}
运行程序,构造类对象效果如下:
如下,C++中对于string类实现了1个析构函数:
该函数没有参数,没有返回值,在类对象生命周期结束后自动调用销毁类对象.
如下,C++98标准中对于string类实现了3个重载的赋值运算符重载函数:
接下来我们演示使用这三种常见的string类赋值运算符重载函数:
如下代码,分别按上述赋值运算符重载函数顺序调用了相应赋值运算符重载函数赋值了3次string类对象s4:
int main()
{
//构造空的string类对象,即空字符串
string s1;
//用C-string来构造string类对象
string s2("hello world");
//string类对象中包含n个字符c
string s3(5, 'x');
//拷贝构造函数
string s4(s2);
cout << s4 << endl;
s4 = s3;
cout << s4 << endl;
s4 = "ABCDEF";
cout << s4 << endl;
s4 = 'Y';
cout << s4 << endl;
return 0;
}
运行程序,赋值运算符重载效果如下:
string类对象的迭代器相关函数共有8个,如下:
string类对象的元素访问相关函数共有四个,如下:
接下来我们演示学习几种常见的string类对象的迭代遍历及元素访问函数: 函数名称功能说明operator[]返回pos位置的字符,const string类对象调用begin+endbegin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器rbegin+rendbegin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器范围forC++支持更简洁的范围for的新遍历方式
operator[]运算符重载定义:operator[]文档链接
operator[]遍历string类对象:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string st1("Hello world");
for (size_t i = 0; i < st1.size(); i++)
{
cout << st1[i] << endl;
}
return 0;
}
operator[]遍历效果如下:
operator[]修改string类对象:
因为operator[]返回的是引用类型,因此可以利用其对string对象进行修改:
int main()
{
string st1("Hello world");
for (size_t i = 0; i < st1.size(); i++)
{
++st1[i];
cout << st1[i] << endl;
}
return 0;
}
operator[]重载访问string类对象和内置类型访问数组成员的区别:
begin+end迭代器顺序遍历访问字符串:
begin()函数定义如下:
end()函数定义如下:
begin+end迭代器顺序遍历访问string类对象:
int main()
{
string st1("Hello world");
//迭代器
string::iterator it = st1.begin();
while (it != st1.end())
{
cout << *it << endl;
++it;
}
return 0;
}
begin+end迭代器顺序遍历访问效果如下:
begin+end迭代器修改string类对象:
int main()
{
string st1("Hello world");
//迭代器
string::iterator it = st1.begin();
while (it != st1.end())
{
++(*it);
cout << *it << endl;
++it;
}
return 0;
}
begin+end迭代器修改string类对象效果如下:
rbegin+rend逆序遍历访问string类对象:
rbegin()函数定义如下:
rend()函数定义如下:
使用rbegin+rend迭代器反向遍历访问string类对象:
int main()
{
string st1("Hello world");
//反向迭代器
string::reverse_iterator rit = st1.rbegin();
while (rit != st1.rend())
{
cout << *rit << endl;
++rit;
}
return 0;
}
rbegin+rend迭代器反向遍历访问string类对象效果如下:
使用rbegin+rend反向迭代器修改string类对象:
int main()
{
string st1("Hello world");
//反向迭代器
string::reverse_iterator rit = st1.rbegin();
while (rit != st1.rend())
{
++(*rit);
cout << *rit << endl;
++rit;
}
return 0;
}
rbegin+rend反向迭代器修改string类对象效果如下:
C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量, 第二部分则表示被迭代的范围。(注:知道数据类型的情况下可以不使用auto关键字自动推导类型)
范围for顺序访问string类对象:
int main()
{
string st1("Hello world");
for (auto ch : st1)
{
cout << ch << endl;
}
return 0;
}
范围for顺序访问string类对象效果如下:
范围for修改string类对象:
int main()
{
string st1("Hello world");
for (auto &ch : st1)
{
ch++;
cout << ch << endl;
}
return 0;
}
范围for修改string类对象效果如下:
注:范围for在底层会替换成迭代器!
string类对象容量相关操作函数共有9个,如下:
接下来我们演示学习几种常见的string类对象的容量操作函数: 函数名称功能说明size返回字符串有效字符长度length返回字符串有效字符长度capacity返回空间总大小empty检测字符串释放为空串,是返回true,否则返回falseclear清空有效字符reserve为字符串预留空间resize将有效字符的个数改成n个,多出的空间用字符c填充
size()函数定义:
使用size()函数获取字符串有效字符长度:
int main()
{
string st1("Hello world");
cout << st1.size() << endl;
return 0;
}
size()函数效果如下:
length()函数定义:
使用length()函数获取字符串有效字符长度
int main()
{
string st1("Hello world");
cout << st1.length() << endl;
return 0;
}
length()函数效果如下:
capacity()函数定义:
使用cipacity()函数获取string类对象当前存储空间总大小:
int main()
{
string st1("Hello world");
cout << st1.size() << endl;
cout << st1.capacity() << endl;
return 0;
}
capacity()函数效果如下:
关于capacity:
empty()函数定义:
使用empty()函数判断字符串是否为空串:
int main()
{
string st1("Hello world");
string st2;
cout << st1.empty() << endl;
cout << st2.empty() << endl;
return 0;
}
empty()函数效果如下:
clear()函数定义:
使用clear()函数清空字符串:
int main()
{
string st1("Hello world");
cout << st1.empty() << endl;
st1.clear();
cout << st1.empty() << endl;
return 0;
}
clear()函数效果如下:
clear对size和capacity的影响:
int main()
{
string st1("Hello world");
cout << st1.size() << endl;
cout << st1.capacity() << endl;
st1.clear();
cout << st1.size() << endl;
cout << st1.capacity() << endl;
return 0;
}
结论是:
一般而言,clear的改变会让size变成0,但不会影响capacity,因为要缩小容量,就需要重新再开辟空间,代价消耗太大,因此一般不会轻易改变capacity的大小:
reserve()函数定义:
使用reserve()函数更改类对象容量:
int main()
{
string st1;
cout << st1.capacity() << endl;
st1.reserve(100);
cout << st1.capacity() << endl;
string st2("Hello this world");
cout << st2.capacity() << endl;
st2.reserve(100);
cout << st2.capacity() << endl;
return 0;
}
reserve()函数效果如下:
resize()函数定义:
使用resize()函数调整字符串大小:
int main()
{
string st1("Hello this world");
cout << "st1:" << endl << st1 << endl;
cout << st1.size() << endl;
cout << st1.capacity() << endl;
st1.reserve(100);
cout << st1 << endl;
cout << st1.size() << endl;
cout << st1.capacity() << endl << endl ;
string st2("Hello this world");
cout << "st2:" << endl << st2 << endl;
cout << st2.size() << endl;
cout << st2.capacity() << endl;
st2.resize(100);
cout << st2 << endl;
cout << st2.size() << endl;
cout << st2.capacity() << endl;
return 0;
}
resize()函数效果如下:
resize在调整容量时也可以用指定的字符来填充,如:
注意:
string类对象的字符串修改函数共有21个,如下:
常用的字符串修改操作: 函数名称功能说明push_back在字符串后尾插字符cappend在字符串后追加一个字符串operator+=在字符串后追加字符串strc_str返回C格式字符串find+nops从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置substr在str中从pos位置开始,截取n个字符,然后将其返回
push_back()函数定义:
使用push_back()函数在string类对象后追加字符:
int main()
{
string st1("Hello worl");
cout << st1 << endl;
cout << st1.size() << endl;
st1.push_back('d');
cout << st1 << endl;
cout << st1.size() << endl;
return 0;
}
push_back()函数效果如下:
append()函数定义:
append()函数一共实现了7个重载函数,但我们日常对于要在字符串后追加内容的场景使用operator+=的次数更多,因此后面会重点介绍operator+=:
使用append()函数在string类对象后追加内容:
int main()
{
string st1("Hello worl");
cout << st1 << endl;
cout << st1.size() << endl;
st1.append("ddddd!");
cout << st1 << endl;
cout << st1.size() << endl;
return 0;
}
append()函数效果如下:
operator+=()函数定义:
使用operator+=()函数在string类对象后追加string类对象内容:
int main()
{
string st1("Hello ");
string st2("world");
cout << st1 << endl;
cout << st2 << endl;
st1 += st2;
cout << st1 << endl;
return 0;
}
operator+=()函数效果如下:
使用operator+=()函数在string类对象后追加常量字符串内容:
int main()
{
string st1("Hello ");
cout << st1 << endl;
st1 += "world";
cout << st1 << endl;
return 0;
}
operator+=()函数效果如下:
使用operator+=()函数在string类对象后追加常量字符内容:
int main()
{
string st1("Hello ");
cout << st1 << endl;
st1 += '!';
cout << st1 << endl;
return 0;
}
operator+=()函数效果如下:
c_str函数定义:
使用c_str()函数返回c格式字符串:
c_str主要是考虑到部分项目中不兼容C++只能转换成C的情况,如下,fopen函数不支持传入string类:
如果想要在C++文件中使用C语言函数且参数是string类的话,就可以调用c_str()函数将string类对象转换为C语言字符串:
int main()
{
string filename("Hello");
fopen(filename.c_str(), "r");
return 0;
}
c_str()函数效果如下:
find+nops函数 find函数定义:
nops函数定义:
使用find+nops函数在string类对象pos位置开始向后寻找字符c: find+nops函数效果如下:
rfind()函数 rfind()函数定义:
使用rfind()函数在string类对象pos位置开始向前寻找字符c: rfind()函数效果如下:
substr()函数 substr()函数定义:
使用substr()函数在string类对象中从pos位置开始,截取n个字符并返回: substr()函数效果如下:
非成员函数重载共有6个,如下:
常用的非成员函数 函数名称功能说明operator+尽量少用,因为传值返回,导致深拷贝效率低operator>>输入运算符重载operator<<输出运算符重载getline获取一行字符串relational operators大小比较
operator+()函数定义:
使用operator+()函数完成string类对象和常量字符串相加:
int main()
{
string st1("Hello ");
string st2 = st1 + "world";
cout << st2 << endl;
return 0;
}
operator+()函数效果如下:
operator>>()函数定义:
使用operator>>()函数从流中提取字符串:
int main()
{
string st1;
cin >> st1;
cout << st1 << endl;
return 0;
}
operator>>()函数效果如下:
operator<<()函数定义:
使用operator<<()函数在string类对象后追加内容:
int main()
{
string st1("hello!");
cout << st1;
return 0;
}
operator<<()函数效果如下:
getline()函数定义:
使用getline()函数将行从流中获取到字符串:
int main()
{
string st1;
std::getline(cin,st1);
cout << st1 << endl;
return 0;
}
getline()函数效果如下:(使用getline流插入字符时可以无视空格,直到遇到回车才截止)
relational operators定义:
使用relational operators比较字符串:
int main()
{
string st1("hello");
string st2("world");
cout << (st1 > st2) << endl;
cout << (st1 >= st2) << endl;
cout << (st1 == st2) << endl;
cout << (st1 != st2) << endl;
cout << (st1 <= st2) << endl;
cout << (st1 < st2) << endl;
return 0;
}
relational operators效果如下: