C++ string类
主要内容
string类:构造对象、获取长度、访问元素、比较大小、修改内容、输入输出、查找、迭代器
构造函数:创建string对象
要初始化一个string对象,可以使用 C 风格字符串或string对象,也可以使用 C 风格字符串的部分或string类型对象的部分或序列,或者使用string对象提供的
迭代器
或
(const) char*
指针。
常见的string类构造函数
下面的两段代码中,约定使用以下标识符带代表相应变量或对象:
(const) char *
);
1 |
string s(); //生成空字符串 |
有关使用迭代器或
(const) char*
指针构造string对象的详细说明:
1 |
string s(str.begin(), str.end()); //等价于string s(str); |
注:第二个参数不用考虑越界问题,但是两个迭代器(指针)位置不能反,否则程序会崩溃。
注意: 不能使用字符或者整数去初始化字符串 。
如果字符串只包含一个字符,使用构造函数对其初始化时,使用以下形式比较合理:
1 |
string s(1, 'x'); //正确 |
(const) char*
与 string 对象
目前,在C++中存在从
const char*
到string的隐含类型转换,但不存在从string对象到C风格字符串的自动类型转换。
一般来说,任何出现字符串字面值的地方都可以用以 空字符结束的字符数组 来替代:
但应注意的是:如果程序的某处需要一个 C风格字符串 ,无法直接用string对象来代替它。
例如 不能用string对象直接初始化指向字符的指针。
为了完成该功能,string专门提供了一个名为c_str的成员函数,返回结果是一个指针,该指针指向一个以空字符(
‘\0’
)结束的字符数组,所存的数据与string对象的相同。结果指针的类型是const char*,从而
不可以
改变返回的字符数组的内容(即返回的是右值)。
1 |
char *s1 = s; //错误:不能用string对象初始化char* |
注意:在整个程序中应坚持使用string对象,直到必须将内容转化为
char*
时才将其转换为C 风格字符串。
例 string类构造函数
1 |
char c_str[] = "01234567"; |
使用cout输出结果
1 |
s0: |
获取字符串长度
string对象包括三种求解字符串长度的函数:
size()
和
length()
、
maxsize()
、
capacity()
。
size()
和
length()
:都会返回string对象中的字符个数,且执行效果相同。
maxsize()
:
maxsize()
函数返回string对象
最多
包含的字符数(一般为int所能容纳的最大值)。一旦程序使用长度超过
maxsize()
的string操作,编译器会拋出length_error异常。
capacity()
:该函数返回
在重新分配内存之前
,string对象所能包含的最大字符数。
string类还具有一个
reserve()
函数。调用该函数可以为string对象重新分配内存,大小由其参数决定,默认参数为0。
访问字符串元素
字符串中元素是可以访问的,一般有两种方法访问字符串中的单一字符:下标操作符
[]
和 成员函数
at()
。两者均返回指定的下标位置的字符。
需要注意的是,这两种访问方法是有区别的 (在VS2019下):
[]
在使用时不检查索引的有效性,如果下标超出字符串的长度范围,会示导致未定义行为。
'\0'
,下标等于字符串长度)是有效的;下标越界(大于字符串长度)会导致Warning:读取数据无效,索引超出了的有效范围。
str.length()
的下标访问是有效的,调用返回字符
'\0'
;下标越界(大于
length()
)会导致传入无效参数而程序崩溃。
at()
在使用时会检查下标是否有效。如果给定的下标超出范围
[0, length())
,系统会抛出out_of_range异常。
例 下标访问的有效问题
1 |
char cstr[] = "0123456"; |
string对象的比较方法
字符串可以和类型相同的字符串相比较,也可以和具有同样字符类型的字符数组比较。
比较运算符
String 类的常见运算符包括 >、<、==、>=、<=、!=。其意义分别为"大于"、“小于”、“等于”、“大于等于”、“小于等于”、“不等于”。
注意:对于参加比较的两个字符串,任一个字符串均不能为
NULL
,否则程序会异常退出。
compare() 函数
string类的成员函数
compare()
返回一个整数来表示比较结果。
如果比较的串与对象相同返回 0;否则按 字典顺序 比较:对象小于(先于)比较的串返回负值,反之返回正值。该函数支持多参数处理,支持用索引值和长度来定位子串进行比较。
compare() 函数原型:
1 |
// compare [0, size()) with _Right |
compare() 的使用方法:
下面的代码中,约定使用以下标识符带代表相应变量或对象:
char*
);pos为下标表示的位置
1 |
//str([0, size()))与sstr([0, size()))或cstr([cstr, <null>))比较 |
字符串内容的变化
字符串内容的变化包括 修改 和 替换 两种。
这一小节的代码中,约定使用以下标识符带代表相应变量或对象:
str表示原始string对象,sstr表示另一个string对象;cstr表示C风格字符串
ch表示char字符;iter表示string对象的迭代器;pos为下标表示的位置
“cstr的前n个字符” 基本都可以替换为
char*
指针,类似
[_Ptr, _Ptr + _Count)
字符串内容的修改
可以使用多种方法修改字符串的值。例如赋值运算符= ,
assign()
,
erase()
,交换(
swap()
),插入(
insert()
)等。另外,还可通过
append()
函数添加字符。
assign() 函数
使用 assign() 函数可以直接给字符串赋值,并返回复制后字符串的引用。既可以将整个字符串赋值给新串,也可以将字符串的子串赋值给新串。其使用方法如下:
1 |
str.assign(sstr); //直接使用字符串sstr/cstr赋值 |
erase() 函数
erase() 函数可以删除整个字符串或者子串的内容。可以不提供参数,默认删除整个字符串;可以提供下标表示的位置;也可以提供迭代器。若不提供或提供下标表示的位置,则返回删除后字符串的引用;若提供迭代器,则返回指向删除后的下一个元素的迭代器。
1 |
//全部清除(m、n缺省时)\清除子串[pos, size())(n缺省时)\清除子串[pos, pos+n) |
swap() 函数
swap()函数可以交换两个字符串内容,无返回值。
1 |
str.swap(sstr); |
insert() 函数
insert() 函数可以将字符或字符串插入到指定位置。位置可由下标指定(返回插入后的字符串的引用),也可以由迭代器指定(返回插入后下一个元素的迭代器)。
1 |
str.insert(pos, cstr); //在pos前面插人字符串cstr |
不可 在下标指定位置时只插入一个字符,正确的做法如下。
例
在字符串str下标3的位置插入字符
‘Z’
1 |
//错误:str.insert(3, 'Z'); |
append() 函数
append() 函数用于向字符串追加内容,其用法和insert() 函数相差不大,相当于固定pos=npos,iter=end(),但返回值均为返回追加后的字符串的引用。
1 |
str.append(cstr); //追加字符串cstr |
字符串内容的替换
修改指定位置字符的值:下标访问修改。
替换某个子串:成员函数 replace() 。
replace() 函数
replace() 函数可以用于替换字符串,返回替换后的字符串的引用。
使用下标指定的位置:
1 |
//1. 将源串的[pos, pos+n)部分使用cstr替换 |
使用迭代器:
和下标的形式差别不大,函数的前两个参数换为
iter1
和
iter2
,表示源串的
[iter1, iter2)
部分。
1 |
//1. [iter1, iter2) -> cstr |
字符串输入输出操作
“<<” 和 “>>” 提供了C++语言的字符串输入和字符串输出功能。
getline() 函数
getline() 函数可将整行的所有字符读到字符串中,并且读取的方式更加多样。该函数的原型包括两种形式:
1 |
//包含2个参数:第1个参数是输入流对象_Istr;第2个参数是保存输入内容的字符串_Str |
在读取字符时,遇到文件结束符、分界符、回车符时,将终止读入操作,且文件结束符、分界符、回车符在字符串中不会保存;当已读入的字符数目超过字符串所能容纳的最大字符数时,将会终止读入操作。
字符串查找函数
在STL中,字符串的查找可以实现多种功能:
string::npos 静态成员常量
1 |
static const size_t npos = -1; |
npos
是静态成员常量值,值为size_t类型可能的最大值。
当这个值在字符串成员函数中的长度或者子长度被使用时,该值表示**“直到字符串结尾” 。作为返回值他通常被用作表明 没有匹配**。
此常量的值定义为
-1
,由于size_type是无符号类型,故需转换为无符号整数类型,因此它是此类型可表示值的最大值。不过实际值还是取决于size_type的实际定义类型,即无符号整型
unsigned int
的-1或无符号长整型
unsigned long
的-1。
find() 和 rfind()
find() 或 rfind() 函数用于在源串中 查找完全相同的 字符(串)或子串。
find() 或 rfind() 函数没有搜索到期望的字符(或子串),则返回
npos
;若搜索成功,find() 返回搜索到的第 1 个字符或子串的位置,rfind() 返回逆向搜索到的第 1 个字符或子串的位置。
find() 的使用方法:
在下面的代码中,约定使用以下标识符带代表相应变量或对象:
str表示原始string对象,sstr表示另一个string对象;cstr表示C风格字符串
ch表示char字符;pos为下标表示的位置
注:“cstr的前n个字符” 基本都可以替换为
char*
指针,类似
[_Ptr, _Ptr + _Count)
1 |
//在源串str中下标pos位置(默认为0)开始查找1个字符ch |
rfind() 函数的功能和 find() 函数的功能类似,参数情况也类似,不同之处pos默认为npos,逻辑为 在源串中下标pos位置之前 逆向查找。
find_first_of() 和 find_last_of()
find_first_of() 函数和 find_last_of() 函数的使用方式、参数表与上述基本相同。
find_first_of() 函数最容易出错的地方是和 find() 函数搞混。find_first_of() 最大的区别就是如果在一个源串中查找另一个字符串, 如果源串中含有另一个字符串中的任何字符(或当实参为字符类型时,源串中含有指定字符),就会查找成功 ,并返回任何一个字符首次在源串中出现的位置(find_last_of() 与 rfind() 的逆向查找相似)。
find_first_not_of() 和 find_last_not_of()
find_first_not_of() 函数和 find_last_not_of() 函数的使用方式、参数表与上述基本相同。
find_first_not_of() 函数可实现在源串中搜索 与指定字符(串)不相等的第 1 个字符 ;find_last_not_of() 函数可实现在源串中搜索 与指定字符(串)不相等的最后 1 个字符 (与 rfind() 的逆向查找相似)。
string类的迭代器
迭代器的定义
1 |
string::iterator 迭代器名称; |
几个常用的迭代器
begin() 和 end() 为正向迭代提供支持;rbegin() 和 rend() 为反向迭代提供支持。
begin() 返回指向字符串第一个字符的迭代器;
end() 返回指向字符串最后一个字符串的后一个位置的迭代器;
rbegin() 返回指向字符串最后一个字符的迭代器;