目录
4.2、字符串的取值和修改操作之at方法和重载operator[]方法的区别
一、简介:
string中文意思是字符串,string是一个类,在C++语言中,string类型不属于基础类型,string是一个模板类,实例化就是一个对象。也可以理解为他是一个可以操作字符串的类。
基础类型有八种:byte、boolean、char、short、int、float、long、double
string模板类原型:
template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>>
class basic_string;
定义了一个名为basic_string
的模板类,它有三个模板参数:CharT
、Traits
和Allocator
。这些参数分别指定了字符类型、字符特性和分配器类型用于分配内存。
CharT
参数表示字符类型,通常使用char
来表示普通的字符串。Traits
参数表示字符操作的特性,比如比较、复制等。Allocator
参数表示内存分配器类型,用于在运行时分配和释放内存。
二、string的构造函数
string类
* string();//默认无参构造函数
* string(const string &str);//默认拷贝构造函数
* string(const char *str);//有一个参数的有参构造函数,使用char *类型初始化string对象
* string(int n,char c);//有两个参数的有参构造函数,第一个参数表示使用的数量,第二个参数表示数据,即使用n个字符c 初始化string对象
#include <iostream>
#include<string>
using namespace std;
/*
* string();//默认无参构造函数
* string(const string &str);//默认拷贝构造函数
* string(const char *str);//有一个参数的有参构造函数,使用char *类型初始化string对象
* string(int n,char c);//有两个参数的有参构造函数,第一个参数表示使用的数量,第二个参数表示数据,即使用n个字符c 初始化string对象
*/
void test(){
string str1("hello,world!");//有一个参数的有参构造函数,string类的对象是str1
cout<<str1<<endl;//可以直接把对象当做字符串遍历
string str2(9,'H');//有两个参数的有参构造函数。string类的对象是str2
cout<<str2<<endl;
string str3(str1);//拷贝构造函数
cout<<str3<<endl;
const char *str4="hello,string类";
string str5(str4);//一个参数的有参构造函数
cout<<str5<<endl;
}
int main()
{
test();//调用函数
return 0;
}
输出结果:
注意 char *str4="hello,string类";虽然编译通过,但是会报警告,因为这是错误的写法,"hello,string类"是一个常量,而char *str4是一个指针类型变量,正确的写法应该是 加const修饰,修饰指针不可更改,即const *str4="hello,string类";
三、string的赋值操作
string &operator=(const char *s);//重载赋值运算符,使用c风格的字符串类型赋值给当前对象
string &operator =(const string &str);//把str对象赋值给当前对象
string &operator =(char c);//字符赋值给当前对象
string &assign(const char *s);//把字符串赋值给当前对象
string &assign(const char *s,int n);//把字符串s的前n个字符赋值给当前对象
string &assign(const string &s);//把字符串s赋值给当前对象
string &assign(int n,char c);//用n个字符c赋值给当前对象
string &assign(const string &s,int start,int n);//将s从start开始的n个字符赋值给当前对象
#include <iostream>
#include<string>
using namespace std;
void test1(){
/*
string &operator=(const char *s);//重载赋值运算符,使用c风格的字符串类型赋值给当前对象
string &operator =(const string &str);//把str对象赋值给当前对象
string &operator =(char c);//字符赋值给当前对象
string &assign(const char *s);//把字符串赋值给当前对象
string &assign(const char *s,int n);//把字符串s的前n个字符赋值给当前对象
string &assign(const string &s);//把字符串s赋值给当前对象
string &assign(int n,char c);//用n个字符c赋值给当前对象
string &assign(const string &s,int start,int n);//将s从start开始的n个字符赋值给当前对象
*/
string str1;
str1="hello,stringC风格赋值操作";
string str2;
str2=str1;//对象赋值
string str3;
str3='H';//字符赋值
string str4;
const char *str0="hello,C风格的字符串";
str4.assign(str0);//C风格字符串通过assign函数赋值
string str5;
str5.assign(str0,5);//前5个字符赋值给当前对象
string str6;
str6.assign(str5);//把str5对象赋值给str6对象
string str7;
str7.assign(9,'H');//把9个H赋值给当前对象
string str8;
str8.assign(str4,5,4);//将str4的从第五个字符开始的4个字符赋值给当前对象
//遍历8个对象
cout<<str1<<endl;
cout<<str2<<endl;
cout<<str3<<endl;
cout<<str4<<endl;
cout<<str5<<endl;
cout<<str6<<endl;
cout<<str7<<endl;
cout<<str8<<endl;
}
int main()
{
test1();//调用函数
return 0;
}
输出结果:
注意:一个汉字,占两个字符 ,这里使用的是Qt软件 编码格式使用默认的system,一般是utf8编码
四、string的取值和修改操作
4.1、string的取值和修改操作
/*
char &operator[](int n);//重载[]运算符,n是下标
char &at(int n);//通过at方法获取下标为n的元素
*/
#include <iostream>
#include<string>
using namespace std;
void test2(){
/*
char &operator[](int n);//重载[]运算符,n是下标
char &at(int n);//通过at方法获取下标为n的元素
*/
string str1="hello,string类";//赋值运算符赋值初始化,一般不建议,在这里可以用,因为是常量,不会发生隐式转换
string str2("hello,string类");//直接赋值初始化,建议使用该方法
str2[4]='H';//将字符串第五个元素改为H
cout<<str2<<endl;
cout<<str2[4]<<endl;
str1.at(1)='E';//使用at方法取值然后修改值
cout<<str1<<endl;
cout<<str1[1]<<endl;
}
int main()
{
test2();//调用函数
return 0;
}
输出结果:
4.2、字符串的取值和修改操作之at方法和重载operator[]方法的区别
使用重载operator[]运算符方法,下标越界不会抛出异常
#include <iostream>
#include<string>
using namespace std;
void test2(){
/*
char &operator[](int n);//重载[]运算符,n是下标
char &at(int n);//通过at方法获取下标为n的元素
*/
string str1="hello,string类";//赋值运算符赋值初始化,一般不建议,在这里可以用,因为是常量,不会发生隐式转换
string str2("hello,string类");//直接赋值初始化,建议使用该方法
str2[4]='H';//将字符串第五个元素改为H
cout<<str2<<endl;
cout<<str2[4]<<endl;
str1.at(1)='E';//使用at方法取值然后修改值
cout<<str1<<endl;
cout<<str1[1]<<endl;
try{
str1[100000]='H';//数组下标访问越界,使用operator[]方法不会抛出异常
}
catch(exception &str){
cout<<str.what()<<endl;//接收来自try的异常
}
printf("hello,string测试\n");//测试
}
int main()
{
test2();//调用函数
return 0;
}
输出结果:
使用at方法,下标越界会抛出异常
#include <iostream>
#include<string>
using namespace std;
void test2(){
/*
char &operator[](int n);//重载[]运算符,n是下标
char &at(int n);//通过at方法获取下标为n的元素
*/
string str1="hello,string类";//赋值运算符赋值初始化,一般不建议,在这里可以用,因为是常量,不会发生隐式转换
string str2("hello,string类");//直接赋值初始化,建议使用该方法
str2[4]='H';//将字符串第五个元素改为H
cout<<str2<<endl;
cout<<str2[4]<<endl;
str1.at(1)='E';//使用at方法取值然后修改值
cout<<str1<<endl;
cout<<str1[1]<<endl;
try{
//str1[100000]='H';//数组下标访问越界,使用operator[]方法不会抛出异常
str1.at(100000)='H';//抛出异常,程序不会终止
}
catch(exception &str){
cout<<str.what()<<endl;//接收来自try的异常
}
printf("hello,string测试\n");//测试
}
int main()
{
test2();//调用函数
return 0;
}
输出结果:
tips:at方法抛出异常之后,程序不终止,且抛出异常提示,该大小只有14个字节,100000超过
五、string的拼接操作
/*
string &operator+=(const string &str);//重载+=运算符
string &operator +=(const char *str);//c风格
string &operator +=(const char c);
string &append(const char *s);//append追加方法
string &append(const char *str,int n);
string &append(const string &s);
string &append(const string &s,int pos,int n);
string &append(int n,char c);
*/
#include <iostream>
#include<string>
using namespace std;
void test3(){
/*
string &operator+=(const string &str);//重载+=运算符
string &operator +=(const char *str);//c风格
string &operator +=(const char c);
string &append(const char *s);//append追加方法
string &append(const char *str,int n);
string &append(const string &s);
string &append(const string &s,int pos,int n);
string &append(int n,char c);
*/
string str1="hello,string";
string str2=",world";
str1+=str2;//两个对象相加赋值给str1对象
string str3="hello,baby";
str3+="欢迎来到这个世界!";//C风格相加
string str4("you are welcome");
str4+='H';//字符追加
string str5("baby");
str5.append("hello");//append方法追加
string str6("god");
str6.append("hello,string",2);//前两个追加给str6对象
string str7("luck");
str7.append(str6);
string str8("hi");
str8.append(str4,3,4);
string str9("wow");
str9.append(9,'Q');
//遍历
cout<<str1<<endl;
cout<<str2<<endl;
cout<<str3<<endl;
cout<<str4<<endl;
cout<<str5<<endl;
cout<<str6<<endl;
cout<<str7<<endl;
cout<<str8<<endl;
cout<<str9<<endl;
}
int main()
{
test3();//调用函数
return 0;
}
输出结果:
六、string的查找和替换操作
/*
int find(const string &str,int pos=0) const;//查找str第一次出现的位置,从第pos位置开始查找
int find(const char *s,int pos=0) const;//查找字符s第一次出现的位置,从pos位置开始查找
int find(const char *s,int pos,int n) const;//从pos查找s的前n个字符在当前对象出现的位置
int find(const char c,int pos=0) const;
int rfind(const string &str,int pos=npos) const;//查找最后一次出现的位置
int rfind(const char *s,int pos=npos) const;
int rfind(const char *s,int pos,int n) const;
int rfind(const char c,int pos=0) const;
string &replace(int pos,int n,const string &str);//replace替换方法,从pos开始到n的位置的元素替换为str
string &replace(int pos,int n,const char *s);
*/
#include <iostream>
#include<string>
using namespace std;
void test4(){
/*
int find(const string &str,int pos=0) const;//查找str第一次出现的位置,从第pos位置开始查找
int find(const char *s,int pos=0) const;//查找字符s第一次出现的位置,从pos位置开始查找
int find(const char *s,int pos,int n) const;//从pos查找s的前n个字符在当前对象出现的位置
int find(const char c,int pos=0) const;
int rfind(const string &str,int pos=npos) const;//查找最后一次出现的位置
int rfind(const char *s,int pos=npos) const;
int rfind(const char *s,int pos,int n) const;
int rfind(const char c,int pos=0) const;
string &replace(int pos,int n,const string &str);//replace替换方法,从pos开始到n的位置的元素替换为str
string &replace(int pos,int n,const char *s);
*/
string str1="helllo,string";
string str2="lll";
int find1=str1.find(str2);
int find2=str1.find("lll");
int find3=str1.find("good",2,3);
int find4=str1.find('h');
int rfind5=str1.rfind(str2);//最后一次出现的位置,其实就是逆序查找
int rfind6=str1.rfind("lll");
int rfind7=str1.rfind("wow",1,2);
int rfind8=str1.rfind('l');
//替换replace
string str3="replace functions";
string str4="#########";
str3.replace(2,4,str4);//从下标为2开始的元素到下标为4结尾的元素替换为str4的元素
string str5="good study";
str5.replace(2,4,"嗨");
string str6="http://www.good.sex.666.sex.age.999.age.com.cn";//将sex和age敏感词屏蔽,sex用*,age用#
while (1) {
int ret=str6.find("sex");
int ret1=str6.find("age");
if(ret==-1&&ret1==-1){
break;
}
str6.replace(ret,3,"***");
str6.replace(ret1,3,"###");
}
//遍历
cout<<find1<<endl;
cout<<find2<<endl;
cout<<find3<<endl;
cout<<find4<<endl;
cout<<rfind5<<endl;
cout<<rfind6<<endl;
cout<<rfind7<<endl;
cout<<rfind8<<endl;
cout<<str3<<endl;
cout<<str5<<endl;
cout<<str6<<endl;
}
int main()
{
test4();//调用函数
return 0;
}
输出结果:
七、string的比较操作
/*
compare方法在>返回1,<返回-1,==返回0;
字符比较根据ASCII码表进行比较
int compare(const string &s) const;
int compare(const char *s) const;
*/
#include <iostream>
#include<string>
using namespace std;
void test5(){
/*
compare方法在>返回1,<返回-1,==返回0;
字符比较根据ASCII码表进行比较
int compare(const string &s) const;
int compare(const char *s) const;
*/
string str1("hello,string");
string str2("helllo,string");
if(str1.compare(str2)==0){
cout<<"相等"<<endl;
}
else if(str1.compare(str2)>0){
cout<<"str1大于str2"<<endl;
}
else{
cout<<"str1小于str2"<<endl;
}
if(str2.compare("hello")==0){
cout<<"相等"<<endl;
}
else if(str2.compare("hello")>0){
cout<<"str2大于'hello'"<<endl;
}
else{
cout<<"str2小于'hello'"<<endl;
}
}
int main()
{
test5();//调用函数
return 0;
}
输出结果:
tips:通过输出结果可知compare方法是逐个字符进行比较
八、string的子串、插入和删除操作
/*
string substr(int pos=0,int n=npos) const;//返回由pos开始的到n组成的字符串
string &insert(int pos,const char *s);//从pos位置插入s
string &insert(int pos,const string &str);
string &insert(int pos,int n,char c);//指定的位置pos插入n个c
string &erase(int pos,int n=npos);//删除从pos开始的n个元素
*/
#include <iostream>
#include<string>
using namespace std;
void test6(){
/*
string substr(int pos=0,int n=npos) const;//返回由pos开始的到n组成的字符串
string &insert(int pos,const char *s);//从pos位置插入s
string &insert(int pos,const string &str);
string &insert(int pos,int n,char c);//指定的位置pos插入n个c
string &erase(int pos,int n=npos);//删除从pos开始的n个元素
*/
string str1="hello,string";
string str2=str1.substr(2,3);
cout<<str2<<endl;
string str3="hello,you are welcome in my eye you are beautiful";
int s=0;
while (1) {
int ret=str3.find(" ",s);//find方法如果查找到了,返回下标位置,查找不到返回-1
if(ret==-1){
cout<<str3.substr(s,str3.size()-s)<<endl;
break;
}
cout<<str3.substr(s,ret-s)<<endl;
s=ret+1;
}
string str4="hello,string";
str4.insert(3,"######");
cout<<str4<<endl;
str4.insert(1,str1);
cout<<str4<<endl;
str4.insert(2,4,'H');
cout<<str4<<endl;
string str5="good,good,stud";
str5.erase(3,4);//删除3到4位置的元素
cout<<str5<<endl;
}
int main()
{
test6();//调用函数
return 0;
}
输出结果:
九、string的C风格和C++风格
/*
* c语言中是没有string类型,因为string是类,是模板类,所以c语言使用指针来使用字符串
* c++使用了C风格的字符串就是这么来的
*/
#include <iostream>
#include<string>
using namespace std;
void test7(){
/*
* c语言中是没有string类型,因为string是类,是模板类,所以c语言使用指针来使用字符串
* c++使用了C风格的字符串就是这么来的
*/
//C风格字符串
const char *str1="hello,C_string";
string str2=str1;
cout<<str2<<endl;
//c++风格字符串
string str3="hello,C++_string";
cout<<str3<<endl;
//c++风格转换为c风格
const char *str4=str3.c_str();
cout<<str4<<endl;//使用c_str方法可以将c++对象转换为c语言风格的char指针类型
}
int main()
{
test7();//调用函数
return 0;
}
输出结果:
string类的使用介绍完毕啦。
真心耗时