目录
string库简介
我们最初在c语言的学习中了解到字符串这个概念,他是多个字符按照一定的顺序排列组合称为字符串,其以 ’\0‘ 字符标志结尾,在C语言中我们也接触到一些处理字符串的函数:strcpy()
、sprintf()
。而且我们通常对指针的操作完成对字符串的遍历,也可通过数组对其进行处理。
要使用string类则需要包含头文件 < string >
,在STL中只有一个字符串类即basic_string
,其中所包含两个预定义类型:包含 char 的 string 类型和包含 wchar 的 wstring 类型。其可管理以 ’\0‘ 字符结尾的字符数组,字符类型由模板参数决定,我们将通过只读指针来访问缓冲区,写操作由类的成员函数实现,C++标准库中的string类不用考虑内存大小和字符串长度等问题。
通过抽象出来的字符串对象,可使用 “=” 进行赋值,使用 “==” 进行字符串间的等值比较,使用 “+” 做串间的串联。
string类成员函数
string类提供了各种操作函数大致分为八类:构造器和析构器、大小和容量、元素存取、字符串比较、字符串修改、字符串接合、I/O操作及搜索和查找。其函数和功能如下表所示:
函数名称 | 功能 |
---|---|
构造函数 | 产生或复制字符串 |
析构函数 | 销毁字符串 |
=、assign | 给字符串赋新值 |
Swap | 交换两个字符串的内容 |
+=,append( ),push_back() | 添加字符 |
insert( ) | 插入字符 |
erase( ) | 删除字符 |
clear( ) | 移除全部字符 |
resize( ) | 改变字符数量 |
replace( ) | 替换字符 |
+ | 串联字符串 |
==,!=,<,<=,>,>=,compare() | 比较字符串内容 |
size( )、length( ) | 返回字符数量 |
max_size( ) | 返回字符的最大可能个数 |
empty( ) | 判断字符串是否为空 |
capacity( ) | 返回重新分配前的字符容量 |
reserve( ) | 保留内存用来存储一定数量的字符,默认参数为0 |
[ ]、at( ) | 存取单一字符 |
>>、getline( ) | 从stream中读取某值 |
<< | 将值写入stream |
copy( ) | 将内容复制为一个 C - string |
c_str( ) | 将内容以C - string形式返回 |
data( ) | 将内容以字符数组形式返回 |
substr( ) | 返回子字符串 |
find( ) | 搜寻某子字符串或字符 |
begin( ),end( ) | 提供正向迭代器支持 |
rbegin( ),rend( ) | 提供逆向迭代器支持 |
get_allocator( ) | 返回配置器 |
string类构造函数和析构函数
构造函数有四个参数,其中三个具有默认值,常见的string构造函数如下:
string strs //生成空字符串
string s(str) //生成字符串str的复制串
string s(str,stridx) //将字符串str中开始于stridx的部分作为构造函数初值
string s(cstr) //以C_string类型cstr作为字符串s的初值
string s(cstr,char_len) //以C_string类型cstr的前char_len个字符串作为字符串s的初值
strings(num, c) //生成一个字符串,包含num个c字符
strings(strs, beg, end) //以区间[beg, end]内的字符作为字符串s的初值
析构函数形式如下:
~string() //销毁所有内存,释放内存
需要注意的是不可用字符或整数初始化字符串,那么我们如果要将对字符串初始化为一个字符的时候有以下两种可用形式:
//正确
std::string s(1, 'x');
std::string s("x");
//错误
std::string s('x')
C_string一般被看做常规的C++字符串,而C++中也存在const char*到 string的隐式类型转换,不存在string到C_string的自动转换,但可通过c_str()
函数实现。构造函数的使用如下:
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str ("12345678");
char ch[ ] = "abcdefgh";
string a; //定义一个空字符串
string str_1 (str); //构造函数,全部复制
string str_2 (str, 2, 5); //构造函数,从字符串str的第2个元素开始,复制5个元素,赋值给str_2
string str_3 (ch, 5); //将字符串ch的前5个元素赋值给str_3
string str_4 (5,'X'); //将 5 个 'X' 组成的字符串 "XXXXX" 赋值给 str_4
string str_5 (str.begin(), str.end()); //复制字符串 str 的所有元素,并赋值给 str_5
cout << str << endl;
cout << a << endl ;
cout << str_1 << endl;
cout << str_2 << endl;
cout << str_3 << endl;
cout << str_4 << endl;
cout << str_5 << endl;
return 0;
}
运行结果为:
12345678
12345678
34567
abcde
XXXXX
12345678
string类获取字符串长度
string类的对象包括三种求解字符串长度的函数:size()
、length()
、maxsize()
和capacity()
:
size()
和length()
这两个函数会返回string类型对象中的字符个数,且效果相同;max_size()
函数返回string类型对象最多包含的字符数,若长度超过最大长度则会抛出length_error异常的错误;capacity()
该函数返回再重新分配内存前,string类对象所包含的最大字符数。
示例代码如下:
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int size = 0;
int length = 0;
unsigned long maxsize = 0;
int capacity=0;
string str ("12345678");
string str_custom;
str_custom = str;
size = str_custom.size();
length = str_custom.length();
maxsize = str_custom.max_size();
capacity = str_custom.capacity();
cout << "size = " << size << endl;
cout << "length = " << length << endl;
cout << "maxsize = " << maxsize << endl;
cout << "capacity = " << capacity << endl;
return 0;
}
运行结果如下:
size = 5
length = 5
maxsize = 2147483647
capacity = 15
string类获取字符串元素
字符串中的元素是可以访问的,一般有两种方法访问单一字符:下标操作符[ ]
和成员函数at( )
,二者均返回指定下标位置的字符,第一个字符的下标为0,最后的字符下标为length( )-1。两种方法访问有如下区别:
- 下标操作符[ ]在使用时不检查索引的有效性,若下标超出长度范围则会导致未定义行为,对于常量字符串,字符串的最后字符(’\0’)是有效的,即调用 [length()-1] = ‘\0’;
- 函数 at( ) 在使用时会检查下标是否有效,若给定下标超出字符长度,则系统会抛出 out_of_range 异常。
示例代码如下:
#include <iostream>
#include <string>
int main()
{
std::string s("abode");
char temp = 0;
char temp1 = 0;
char temp2 = 0;
temp = s[2]; //"获取字符 'c'
temp1 = s.at(2); //获取字符 'c'
temp2 = s[s.length()];//获取字符 '/0'
//temp3 = s.at(s.length()); //程序异常
std::cout << temp << temp1 << temp2 << std::endl;
std::cout << s << std::endl;
char& r = s[2]; //建立引用关系
char* p = &s[3]; //建立引用关系
r = 'X';//修改内容
*p = 'Y';//修改内容
std::cout << s << std::endl; //输出
s = "12345678"; //重新赋值
r = 'X'; //修改内容
*p = 'Y'; //修改内容
std::cout << s << std::endl; //输出
return 0;
}
运行结果如下:
oo
abode
abXYe
12XY5678
string类比较字符串
字符串可以和类型相同的字符串相比较,也可和有相同字符类型的数组比较,除了类模板提供的>、<、==、>=、<=、!= 比较运算符外还提供了compare()
函数,该函数返回一个整数表示结果,若相同返回0,若字符串 S 按字典顺序要先于 S2,则返回负值;反之,则返回正值。
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string A ("aBcdef");
string B ("AbcdEf");
string C ("123456");
string D ("123dfg");
//下面是各种比较方法
int m=A.compare (B); //完整的A和B的比较
int n=A.compare(1,5,B); //"Bcdef"和"AbcdEf"比较
int p=A.compare(1,5,B,4,2); //"Bcdef"和"Ef"比较
int q=C.compare(0,3,D,0,3); //"123"和"123"比较
cout << "m = " << m << ", n = " << n <<", p = " << p << ", q = " << q << endl;
cin.get();
return 0;
}
运行结果如下:
m = 1, n = 1, p = -1, q = 0
也可使用比较运算符实现字符串的大小比较,在使用比较运算符时应注意支付传不能为NULL否则会异常退出。
string类字符串内容修改
可通过使用多个函数修改字符串的值,例如assign()
、operator=
、erase()
、交换(swap)、插入(insert)等,另外可通过append()
函数添加字符。
assign()函数
使用assign()
函数可直接给字符串赋值,即可将整个字符串赋值给新串也可将字符串的子串赋值给新串,示例代码如下:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1("123456");
string str;
str.assign(str1); //直接赋值
cout << str << endl;
str.assign(str1, 3, 3); //赋值给子串
cout << str << endl;
str.assign(str1, 2, str1.npos);//赋值给从位置 2 至末尾的子串
cout << str << endl;
str.assign(5, 'X'); //重复 5 个'X'字符
cout << str << endl;
string::iterator itB;
string::iterator itE;
itB = str1.begin();
itE = str1.end();
str.assign(itB, (--itE)); //从第 1 个至倒数第 2 个元素,赋值给字符串 str
cout << str << endl;
return 0;
}
运行结果如下:
123456
456
3456
XXXXX
12345
operator=函数
operator=的功能就是赋值。
erase()函数
iterator erase (iterator first, iterator last); //函数原型
//erase() 函数的使用方法
str.erase (str* begin(), str.end());
//或
str.erase (3);
swap()函数
void swap (basic_string& str); //函数原型
//swap()函数使用方法
string str2 ("abcdefghijklmn");
str.swap (str2);
insert()函数
函数原型:
basic_string& insert (size_type p0 , const E * s); //插人 1 个字符至字符串 s 前面
basic_string& insert (size_type p0 , const E * s, size_type n); // 将 s 的前 3 个字符插入p0 位置
basic_string& insert (size_type p0, const basic_string& str);
basic_string& insert (size_type p0, const basic_string& str,size_type pos, size_type n); //选取 str 的子串
basic_string& insert (size_type p0, size_type n, E c); //在下标 p0 位置插入 n 个字符 c
iterator insert (iterator it, E c); //在 it 位置插入字符 c
void insert (iterator it, const_iterator first, const_iterator last); //在字符串前插入字符
void insert (iterator it, size_type n, E c) ; //在 it 位置重复插入 n 个字符 c
示例代码如下:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string A("ello");
string B("H");
B.insert(1,A);
cout << B << endl;
A = "ello";
B = "H";
B.insert(1, "yanchy ", 3);
cout << B << endl;
A = "ello";
B = "H";
B.insert(1, A, 2, 2);
cout << B << endl;
A = "ello";
B.insert(1, 5, 'C');
cout << B << endl;
A = "ello";
string::iterator it = B.begin() + 1;
const string::iterator itF = A.begin();
const string::iterator itG = A.end();
B.insert(it, itF, itG);
cout << B << endl;
return 0;
}
运行结果如下:
Hello
Hyan
Hlo
HCCCCClo
HelloCCCCClo
append 函数
函数原型:
basic_string& append (const E * s); //在原始字符串后面追加字符串s
basic_string& append (const E * s, size_type n);//在原始字符串后面追加字符串 s 的前 n 个字符
basic_string& append (const basic_string& str, size_type pos,size_type n);//在原始字符串后面追加字符串 s 的子串 s [ pos,…,pos +n -1]
basic_string& append (const basic_string& str);
basic_string& append (size_type n, E c); //追加 n 个重复字符
basic_string& append (const_iterator first, const_iterator last); //使用迭代器追加
示例代码:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string A = "ello";
string B = "H";
cout << A << endl;
cout << B << endl;
B.append(A);
cout << B << endl;
B.append("12345", 2);
cout << B << endl;
A = "ello";
cout << A << endl;
cout << B << endl;
B.append("12345", 2, 3);
cout << B << endl;
A = "ello";
B = "H";
cout << A << endl;
cout << B << endl;
B.append(10, 'a');
cout << B << endl;
A = "ello";
B = 'H';
cout << A << endl;
cout << B << endl;
B.append(A.begin(), A.end());
cout << B << endl;
return 0;
}
运行结果:
ello
H
Hello
Hello12
ello
Hello12
Hello12345
ello
H
Haaaaaaaaaa
ello
H
Hello
string类字符串查找
字符串的查找函数非常多,但查找函数也可有很多种实现:
- 搜索单个字符、搜索字串;
- 实现向前搜索、向后搜索;
- 分别实现搜索第一个和最后一个满足条件的字符或字串。
若查找 find() 函数和其他函数没有搜索到期望的字符(或子串),则返回 npos(-1);若搜索成功,则返回搜索到的第 1 个字符或子串的位置,其返回值为 size_type 类型(无符号整数)用来表明字符串中元素个数或者字符在字符串中的位置。
函数原型:
size_type find (value_type _Chr, size_type _Off = 0) const;
//find()函数的第1个参数是被搜索的字符、第2个参数是在源串中开始搜索的下标位置
size_type find (const value_type* _Ptr , size_type _Off = 0) const;
//find()函数的第1个参数是被搜索的字符串,第2个参数是在源串中开始搜索的下标位置
示例代码:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str_ch(" for");
string str(" Hi, Peter, I'm sick. Please bought some drugs for me.");
string::size_type m = str.find('P', 5);
cout << "Example - find() : The position (forward) of 'P' is: " << (int)m << endl;
string::size_type n = str.find(" some", 0);
cout << "Example - find () : The position (forward) of 'some' is: " << (int)n << endl;
return 0;
}
运行结果:
Example - find() : The position (forward) of 'P' is: 5
Example - find () : The position (forward) of 'some' is: 35
参考文章:C++ STL(标准模板库)