文章目录
1 string基本概念
string和char *的区别:
string
:C++风格的字符串;本质是类。string类内部封装char*
的成员属性,是char*型容器,底层维护C语言的字符串。
char *
:C风格的字符串;本质是指针。
特点:
(1)string类
的内部封装了许多用于操作字符串的成员方法,例如:查找find、拷贝copy、删除delete、替换replace、插入insert等。
(2)string类
管理char*
的内存分配时,无需担心复制越界、取值越界、内存释放(析构调用)等,由string类的内部负责管理。
2 string构造函数
构造函数原型:
(1)string();
:默认无参构造函数,创建一个空字符串,如string str;
。
(2)string(const char* s);
:有参构造函数,使用C语言字符串s
初始化一个C++风格字符串。
(3)string(const string& str);
:拷贝构造函数,使用已有string对象初始化新的string对象。
(4)string(int n, char c);
:有参构造函数,使用n个字符c
初始化一个C++风格字符串。
注:string的多种构造方式之间无可比性,灵活使用即可。
示例:string的构造函数
#include<iostream>
#include<string>
using namespace std;
int main() {
/* 默认无参构造 */
string str1;
cout << "str1 = " << str1 << endl; //(空字符串)
/* 有参构造:使用C风格的const char*字符串初始化 */
const char* cstr = "hello cpp";
string str2(cstr);
cout << "str2 = " << str2 << endl; //hello cpp
/* 拷贝构造 */
string str3(str2);
cout << "str3 = " << str3 << endl; //hello cpp
/* 多个字符拼接 */
string str4(5, 'h');
cout << "str4 = " << str4 << endl; //hhhhh
return 0;
}
3 字符串长度【size()、length()、strlen()】
(1)const char*类型
的字符串长度
使用函数strlen(const char* s)
获取字符串长度(不包含'\0'结束符
)。
函数原型:unsigned int strlen(const char *pStr);
注1:运算符
sizeof("xxx")
计算的是占用的内存空间大小(包含'\0'结束符
),而不是字符串长度。
注2:单个英文字符的长度为1
;单个中文字符的长度为2
。
//const char*字符串的长度-英文字符占1个字符长度
cout << strlen("world") << endl; //字符串长度:5(未计算'\0')
cout << sizeof("world") << endl; //内存大小:6字节(计算'\0')
//const char*字符串的长度-中文字符占2个字符长度
cout << strlen("世界和中国") << endl; //字符串长度:10(未计算'\0')
cout << sizeof("世界和中国") << endl; //内存大小:11字节(计算'\0')
(2)string类型
的字符串长度
①使用成员函数size()
或length()
获取字符串长度(不包含'\0'结束符
)。
②string类型
对象可调用成员函数c_str()
转换为const char*类型
,再使用strlen(const char* s)
获取字符串长度,即strlen(str.c_str())
。
函数声明:const char* string::c_str() const;
//string字符串的长度-英文字符占1个字符长度
string str1 = "hello";
cout << "str1的长度:" << str1.length() << endl; //5
cout << "str1的长度:" << str1.size() << endl; //5
cout << "str1的长度:" << strlen(str1.c_str()) << endl; //5
//string字符串的长度-中文字符占2个字符长度
string str2 = "世界和中国";
cout << "str2的长度:" << str2.length() << endl; //10
cout << "str2的长度:" << str2.size() << endl; //10
cout << "str2的长度:" << strlen(str2.c_str()) << endl; //10
4 string赋值操作【operator=、assign()】
作用:通过重载赋值运算符operator=
和成员函数assign()
,对string字符串进行赋值。
注:string的赋值操作,重载赋值运算符
operator=
的方式更常用。
赋值操作的函数原型:
(1)string& operator=(const char* s);
:使用const char*类型的字符串,对当前字符串赋值。
(2)string& operator=(const string &s);
:使用string类型的字符串s
,对当前字符串赋值。
(3)string& operator=(char c);
:使用单个字符,对当前字符串赋值。
(4)string& assign(const char *s);
:使用const char*类型的字符串,对当前字符串赋值。
(5)string& assign(const char *s, int n);
:使用const char*类型的字符串s
的前n个字符(子串),对当前字符串赋值。
(6)string& assign(const string &s);
:使用string类型的字符串,对当前字符串赋值。
(7)string& assign(int n, char c);
:使用n个字符c
,对当前字符串赋值。
示例:string的赋值操作
#include<iostream>
#include<string>
using namespace std;
int main() {
/* 重载赋值运算符operator=赋值 */
//(1)string& operator=(const char* s); :使用const char* 类型的字符串,对当前字符串赋值。
string str1;
str1 = "hello";
cout << "str1 = " << str1 << endl; //hello
//(2)string& operator=(const string& s); :使用string类型的字符串s,对当前字符串赋值。
string str2;
str2 = str1;
cout << "str2 = " << str2 << endl; //hello
//(3)string& operator=(char c); :使用单个字符,对当前字符串赋值。
string str3;
str3 = 'a';
cout << "str3 = " << str3 << endl; //a
//(4)string& assign(const char* s); :使用const char* 类型的字符串,对当前字符串赋值。
string str4;
str4.assign("world");
cout << "str4 = " << str4 << endl; //world
//(5)string& assign(const char* s, int n); :使用const char* 类型的字符串s的前n个字符(子串),对当前字符串赋值。
string str5;
str5.assign("world", 2);
cout << "str5 = " << str5 << endl; //wo
//(6)string& assign(const string & s); :使用string类型的字符串,对当前字符串赋值。
string str6;
str6.assign(str5);
cout << "str6 = " << str6 << endl; //wo
//(7)string& assign(int n, char c); :使用n个字符c,对当前字符串赋值。
string str7;
str7.assign(5, 'h');
cout << "str7 = " << str7 << endl; //hhhhh
return 0;
}
5 string字符串拼接【operator+=、append()】
作用:通过重载加法赋值运算符operator+=
和成员函数append()
,实现在源字符串的末尾拼接目标字符串(尾部追加)。
字符串拼接操作的函数原型:
(1)string& operator+=(const char* str);
:将const char*类型的字符串,拼接至原字符串结尾。
(2)string& operator+=(const char c);
:将单个字符,拼接至原字符串结尾。
(3)string& operator+=(const string& str);
:将string类型的字符串,拼接至原字符串结尾。
(4)string& append(const char *s);
:将const char*类型的字符串,拼接至原字符串结尾。
(5)string& append(const char *s, int n);
:将const char*类型的字符串s
的前n
个字符,拼接至原字符串结尾。
(6)string& append(const string &s);
:将string类型的字符串,拼接至原字符串结尾。
(7)string& append(const string &s, int pos, int n);
:将string类型的字符串s
中自索引位置pos
起的n
个字符(长度为n的子串),拼接至原字符串结尾。
注:成员函数
append(const string &s, int pos, int n);
截取的字符串,包含索引位置pos
本身的字符。
示例:string的字符串拼接操作
#include<iostream>
#include<string>
using namespace std;
/* 字符串拼接 */
int main() {
//(1)string& operator+=(const char* str);
//将const char* 类型的字符串,拼接至原字符串结尾。
string str1 = "我";
str1 += "爱学习";
cout << "str1 = " << str1 << endl; //我爱学习
//(2)string& operator+=(const char c);
//将单个字符,拼接至原字符串结尾。
str1 += ':';
cout << "str1 = " << str1 << endl; //我爱学习:
//(3)string& operator+=(const string & str);
//将string类型的字符串,拼接至原字符串结尾。
string str2 = "C++";
str1 += str2;
cout << "str1 = " << str1 << endl; //我爱学习:C++
//(4)string& append(const char* s);
//将const char* 类型的字符串,拼接至原字符串结尾。
str1.append("/Python");
cout << "str1 = " << str1 << endl; //我爱学习:C++/Python
//(5)string& append(const char* s, int n);
//将const char* 类型的字符串s的前n个字符,拼接至原字符串结尾。
str1.append("/JavaWeb", 5);
cout << "str1 = " << str1 << endl; //我爱学习:C++/Python/Java
//(6)string& append(const string & s);
//将string类型的字符串,拼接至原字符串结尾。
string str3 = "/MySQL";
str1.append(str3);
cout << "str1 = " << str1 << endl; //我爱学习:C++/Python/Java/MySQL
//(7)string& append(const string & s, int pos, int n);
//将string类型的字符串s中自索引位置pos起的n个字符(长度为n的子串),拼接至原字符串结尾。
string str4 = "Windows/Linux";
str1.append(str4, 7, 6);
cout << "str1 = " << str1 << endl; //我爱学习:C++/Python/Java/MySQL/Linux
return 0;
}
6 string查找【find()、rfind()】和替换【replace()】
(1)查找:通过成员函数find()
或rfind()
,查找指定字符串是否存在。
find()
和rfind()
的区别:find()
从左往右查找;rfind()
从右往左查找。
函数原型:
①int find(const string& str, int pos = 0) const;
【从左往右查找,第一次出现位置】
从源字符串的指定索引位置pos
(默认为0)起,查找string类型的目标字符串str
第一次出现的索引位置。查找到,则返回匹配处第1个字符的索引位置;未查找到,则返回-1
。
②int find(const char* s, int pos = 0) const;
【从左往右查找,第一次出现位置】
从源字符串的指定索引位置pos
(默认为0)起,查找const char*类型的目标字符串s
第一次出现的索引位置。查找到,则返回匹配处第1个字符的索引位置;未查找到,则返回-1
。
③int find(const char* s, int pos, int n) const;
【从左往右查找,第一次出现位置】
从源字符串的指定索引位置pos
起,查找const char*类型的目标字符串s
的前n
个字符第一次出现的索引位置。查找到,则返回匹配处第1个字符的索引位置;未查找到,则返回-1
。
④int find(const char c, int pos = 0) const;
【从左往右查找,第一次出现位置】
从源字符串的指定索引位置pos
(默认为0)起,查找目标字符c
第一次出现的索引位置。查找到,则返回匹配处第1个字符的索引位置;未查找到,则返回-1
。
⑤int rfind(const string& str, int pos = npos) const;
【从右往左查找,第一次出现位置】
从源字符串的指定索引位置pos
(默认为npos
,即-1
)起,查找string类型的目标字符串str
最后一次出现的索引位置。查找到,则返回匹配处第1个字符的索引位置;未查找到,则返回-1
。
注1:
npos
是string类的静态常量,表示字符串中不存在的位置,即结束位置
,通常表示为-1
。
定义:static const size_type npos = -1;
注2:判断源字符串src
是否包含目标字符串dest
的方法:
if (src.find(dest) != string::npos){...}
⑥int rfind(const char* s, int pos = npos) const;
【从右往左查找,第一次出现位置】
从源字符串的指定索引位置npos
(默认为npos
,即-1
)起,查找const char*类型的目标字符串s
最后一次出现的索引位置。查找到,则返回匹配处第1个字符的索引位置;未查找到,则返回-1
。
⑦int rfind(const char* s, int pos, int n) const;
【从右往左查找,第一次出现位置】
从源字符串的指定索引位置pos
起,查找const char*类型的目标字符串s
的前n
个字符最后一次出现的索引位置。查找到,则返回匹配处第1个字符的索引位置;未查找到,则返回-1
。
⑧int rfind(const char c, int pos = 0) const;
【从右往左查找,第一次出现位置】
从源字符串的指定索引位置pos
(默认为0)起,查找目标字符c
最后一次出现的索引位置。查找到,则返回匹配处第1个字符的索引位置;未查找到,则返回-1
。
示例:字符串查找
#include<iostream>
#include<string>
using namespace std;
/* 字符串查找 */
void func() {
string str1 = "abcdefgbc";
string str2 = "bc";
//find():从左往右查找,第1次出现位置
int pos1 = str1.find(str2);
if (pos1 != -1) {
cout << "str1包含str2" << endl;
cout << "第一次出现的索引位置为:" << pos1 << endl; //1
}
else {
cout << "str1不包含str2" << endl;
}
//rfind():从右往左查找,第1次出现位置(即从左往右查找时的【最后1次】出现位置)
int pos2 = str1.rfind(str2);
if (pos2 != -1) {
cout << "str1包含str2" << endl;
cout << "最后一次出现的索引位置为:" << pos2 << endl; //7
}
else {
cout << "str1不包含str2" << endl;
}
}
(2)替换:在指定位置替换字符串。
函数原型:
①string& replace(int pos, int n, const string& str);
将源字符串指定索引位置pos
起的连续n
个字符,替换为string类型的整个目标字符串str
。
②string& replace(int pos, int n, const char* s);
将源字符串指定索引位置pos
起的连续n
个字符,替换为const char*类型的整个目标字符串s
。
示例:字符串替换
#include<iostream>
#include<string>
using namespace std;
/* 字符串替换 */
void func2() {
string str1 = "abcdefg";
string str2 = "****";
//replace():将源字符串指定索引位置pos起的连续n个字符,替换为整个目标字符串
str1.replace(1, 2, str2); //将str1的"bc"等2个字符,替换为整个str2
cout << "替换后的str1 = " << str1 << endl; //a****defg
}
7 string字符串比较【compare()】
作用:通过成员函数compare()
比较两个字符串。主要用于判断两个字符串是否相等,即if(s1.compare(s2) == 0)
。
比较方式:逐个比较每个字符的ASCII码:
①相等时,继续比较后一个字符,直至完成所有字符的比较,全部相等则返回0
。
②不等时,大于则返回1
;小于则返回-1
。
函数原型:
(1)int compare(const string &s) const;
:将源字符串与string类型的字符串进行比较。
(2)int compare(const char *s) const;
:将源字符串与const char*类型的字符串进行比较。
示例:字符串比较
#include<iostream>
#include<string>
using namespace std;
int main() {
string str1 = "abc";
string str2 = "acb";
if (str1.compare(str2) == 0) {
cout << "str1 等于 str2" << endl;
}
else if(str1.compare(str2) < 0) {
cout << "str1 小于 str2" << endl; //str1 小于 str2
}
else if (str1.compare(str2) > 0) {
cout << "str1 大于 str2" << endl;
}
return 0;
}
8 string字符存取【operator[]、at()】
作用:通过重载赋值运算符operator[]
和成员函数at(int index)
,对字符串的单个字符进行读(作为右值)或写(作为左值)。
注:
string类型
字符串的底层实际为字符数组,可通过索引访问字符数组的字符元素。
字符存取的2种方式:
(1)char& operator[](int index);
:重载运算符[],读写指定索引位置index
的字符
(2)char& at(int index);
:成员函数,读写指定索引位置index
的字符
示例:
#include<iostream>
#include<string>
using namespace std;
int main() {
/* 重载运算符[]读写字符 */
string str1 = "abcd";
cout << "修改前:str1 = " << str1 << endl; //abcd
//读取字符
cout << "str1[1] = " << str1[1] << endl; //b
//写入字符
str1[1] = 'a';
cout << "修改后:str1 = " << str1 << endl; //aacd
/* 成员函数at()读写字符 */
string str2 = "abcd";
cout << "修改前:str2 = " << str2 << endl; //abcd
//读取字符
cout << "str2.at(1) = " << str2.at(1) << endl; //b
//写入字符
str2.at(1) = 'a';
cout << "修改后:str1 = " << str2 << endl; //aacd
return 0;
}
9 string插入【insert()】和删除【erase()】
(1)字符串插入:使用成员函数insert(..)
在原字符串中插入字符串或字符。
函数原型:
①string& insert(int pos, const char* s);
:在原字符串指定索引位置pos
前插入const char*类型的字符串。
②string& insert(int pos, const string& str);
:在原字符串指定索引位置pos
前插入string类型的字符串。
③string& insert(int pos, int n, char c);
:在原字符串指定索引位置pos
前插入n
个字符。
(2)字符串删除:使用成员函数erase(..)
在原字符串中删除若干个连续字符。
函数原型:
string& erase(int pos, int n = npos);
:从原字符串的指定索引位置pos
开始,连续删除n
个字符。
示例:字符串的插入与删除
#include<iostream>
#include<string>
using namespace std;
int main() {
//insert():在原字符串指定索引位置pos前,插入字符或字符串
string str = "abcd";
str.insert(1, "***"); //在字符b前(索引位置1)插入***
cout << "str = " << str << endl; //a***bcd
//erase():从原字符串的指定索引位置pos开始,连续删除n个字符
str.erase(1, 3); //从索引位置1开始,连续删除3个字符
cout << "str = " << str << endl; //abcd
return 0;
}
10 string获取子串【substr()】
作用:通过成员函数substr(...)
,从原字符串中获取子字符串。
函数原型:
string substr(int pos = 0, int n = npos) const;
从原字符串的指定索引位置pos
开始,截取连续n
个字符作为子字符串并返回。
示例:截取子字符串
#include<iostream>
#include<string>
using namespace std;
int main() {
string str = "helloworld";
//从索引位置5开始截取5个字符并返回子字符串
string newStr = str.substr(5, 5);
cout << "newStr = " << newStr << endl; //world
/* 实际应用场景 */
string email = "[email protected]";
//获取@的索引位置(@前共有pos个字符)
int pos = email.find("@");
//从原字符串索引位置0,截取pos个字符
string username = email.substr(0, pos);
cout << "username = " << username << endl; //NewsomTech
return 0;
}