当前位置: 首页 > news >正文

C++--string类对象

一,引言

string类对象在于更好的处理字符串问题,为对于字符串这一类型提供更加方便的接口和运算符的重载。本片文章首先会引入auto关键字和范围for两个C++11小语法。之后按照如下网站所提供的顺序经行讲解。cplusplus.com - The C++ Resources Networkhttps://legacy.cplusplus.com/

一共分为八个部分,默认成员函数,迭代器, 关于容量的成员函数,元素存取相关函数,修饰符相关函数,针对字符串的操作的函数,全局函数。本篇文章对经常使用的进行详细的介绍,其他的进行略讲,有需求的通过上面的网站有详细的介绍。

二,auto关键字,范围for

1,auto关键字

auto首先不能作用于数值,其次auto不能作为函数的形参的参数类型,当auto同时修饰多个变量时,变量的类型必须一致。否则会导致编译报错。通常来说auto就是通过编译器的推理来确定auto修饰的数据类型。下面提供一些例子:

void text1()
{int a = 0;auto b = a;
}auto fun3()
{return 3;
}int main()
{auto b = fun3();return 0;
}

auto b根据a的类型编译器推到得出b的类型,auto作为函数返回类型是同样根据返回值得出auto具体的返回类型,当使用auto变量去接受函数体是也是根据返回数据的数据类型进而得出auto的具体类型。

以上例子看似得不出来auto得优越性,下面还有一组例子:
 

int main()
{string s1 = "fadslfj";std::string::iterator it = s1.begin();auto s = it;return 0;
}

当数据得类型特别长时,使用auto会大大的减少变量类型的书写长度,使得代码更加简洁。

2,范围for

范围for分为两个部分,第一部分表示范围内使用迭代器,第二部分表示迭代的范围。

范围for具有自动迭代,自动取数据,自动判读结束的性质。其作用范围可用于数组以及容器对象进行迭代。

下面举一些例子:
 

int main()
{int array[] = { 1, 2, 3, 4, 5 };// C++98的遍历for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i){array[i] *= 2;}for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i){cout << array[i] << endl;}// C++11的遍历for (auto& e : array)e *= 2;for (auto e : array)cout << e << " " << endl;string str("hello world");for (auto ch : str){cout << ch << " ";}cout << endl;return 0;
}

头两个是数组普通的数据进行遍历,后面auto表示一个迭代器变量,冒号后面表示迭代器的范围,当使用引用时必须加&。当作用在类对象时也是一样的。

三,默认成员函数

1,构造函数

首先第一个支持无参数的默认构造,第二个,以及第三个为拷贝构造。第四个,第五个支持字符串形式的构造。第六个支持字符形式的构造。

下面举一些例子来看一下效果:
 

void text_string1()
{//传入字符串形式string s1("fsdlkjlsdfjk");//字符串,加个数string s2("asdf", 2);//个数,单个字符string s3(2, 'a');//拷贝构造string s4(s3);//拷贝构造,后加参数的string s5(s1, 1, 3);cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;cout << s5 << endl;
}

第二个就是单纯的拷贝构造--------------s4

第三个表示从原对象的第pos个位置开始拷贝,拷贝长度为npos的字符到原对象--------s5

第四个就是表示传入的类型为字符串类型------------s1

第五个表示传入为字符串类型,n表示截取前n个数据拷贝到原对象 ------------s2

第六个表示传入为字符形式将n个c传入原对象,n表示传入字符的个数,c表示字符数据--s3

2,析构函数

当string对象动态开辟空间时,需要析构函数,由于是编译器自动调用,这次不进行详细的介绍

3,等号(=)运算符的重载

 对于等号运算符的重载一共有三个,第一个是string类型,第二个是字符串类型,第三个是字符类型

来看一下例子:
 

void text_string2()
{std::string str1, str2, str3;str1 = "Test string: ";   // c-stringstr2 = 'x';               // single characterstr3 = str1 + str2;       // stringcout << str1 << endl;cout << str2 << endl;std::cout << str3 << '\n';
}

第一个调用参数为类对象的赋值---------str3

第二个调用参数为字符串类型的赋值-------str1

第三个调用参数为字符类型的赋值--------str2 

四,Iterators(迭代器)

1,begin

 返回第一个字符位置的迭代器,有两个类型第一个用在可修改的对象上,第二个用不可修改的对象上。

来看一组例子:
 

void text_string3()
{string s1("fjdsaklfjlasd");string::iterator it = s1.begin();cout << *it << endl;for (auto it : s1){cout << it ;}
}

第一个打印返回第一个位置的字符,此时的迭代器是指针,所以可以解引用,但是并不是所有的迭代器都是指针。

2,end

 返回最后一个位置的迭代器, 有两个类型第一个用在可修改的对象上,第二个用不可修改的对象上。

来看一组例子:

void text_string4()
{string s1("fjdsaklfjlasd");string::iterator it = s1.end();//cout << *it << endl;cout << *(it-1) << endl;}

打印倒数第二个位置的字符,最后一个位置的字符是用来判断结束条件。当使用迭代器解引用打印最后一个位置的字符会报错。 

3,rbegin

 返回最后一个字符位置的迭代器,有两个类型第一个用在可修改的对象上,第二个用不可修改的对象上。

来看一组例子:
 

oid text_string5()
{string s1("ffdasfaj");cout << s1[8] << endl;string::reverse_iterator it = s1.rbegin();//cout << *it << endl;cout << *it << endl;}

打印的是最后一个有效字符(倒数第二个位置),当rbegin进行++操作是往字符串前面走 。

4,rend

返回end位置的迭代器,也就是最后一个位置 。有两个类型第一个用在可修改的对象上,第二个用不可修改的对象上。

来看一组例子:
 

void text_string6()
{string s1("ffdasfaj");cout << s1[8] << endl;string::reverse_iterator it = s1.rend();cout << *(it-1) << endl;cout << *it << endl;}

当时(rend-1)时打印了第一个位置的字符,rend是发生了报错,因为rend和end指向的是一个位置,所以报错原因都是一样的。

要注意的是rbegin和rend的++,--都是相反的,要和begin和end区别开。 

五,关于容量的成员函数

1,size

返回有效字符的个数。

来看一组例子: 

void text_string10()
{string s1("ffdasfaj");cout << s1.size() << endl;
}

 需要注意是有效字符,不包括最后判断字符,以及和容量的大小无关

2,length

length和size的用法完全一致。 

3,max_size

返回字符串能达到的最大长度,主要用于对字符串对象一个最大长度的限制。

4,resize

作用于对长度的修改,两个类型,表示对string对象长度修改为n。

分为两种情况,当n小于size时,删除size之后的数据。当n大于size时对string对象进行扩容填充,直到填充到n个字符,第一个类型进行默认填充,第二个类型自己输入字符填充。 

来看一组例子:
 

void text_string11()
{string s1("ffdasfaj");cout << s1.size() << endl;cout << s1 << endl;s1.resize(5);cout << s1.size() << endl;cout << s1 << endl;s1.resize(20);cout << s1.size() << endl;cout << s1 << endl;s1.resize(25,'b');cout << s1.size() << endl;cout << s1 << endl;
}

 原对象是8个字符,长度为8,第一个resize(5)小于size,这个函数会对此对象删除5以后的数据

。第二个resize(20)大于size,没有传入参数,编译器填入默认参数。第三个resize(25),比size大

5,所以填入5个b。

5,capacity

计算string对象容量的大小,并不等于size的长度。 

6,reverse

对string对象的容量进行改变。函数参数n大于对象容量,会对该对象进行扩容,扩容的大小大于等于n。当n小于对象容量,若n小于size则对该对象不做处理。若n大于size小于容量,这种情况编译器自行处理,可能缩容也可能不做处理。

来看一组例子:

void text_string12()
{string s1("ffdasfaj");cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;string s2("ffdasfaj");s1.reserve(5);cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;string s3("ffdasfaj");s1.reserve(20);cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;s1.reserve(15);cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1 << endl;
}

 

第一组数据对原对象的size,capacity记录原始数据。

第二组当n小于size时,size,capacity都不变数据不受影响

第三组当n大于capacity时,size不变,capacity进行扩容,进行整数倍扩容,capacity大于n

第四组当n大于size小于capacity时,size不变,capacity进行缩容 

7,clear

清除字符串,使得size为0,capacity不变

来看一组例子:

void text_string13()
{string s1("ffdasfaj");cout << s1.size() << endl;cout << s1.capacity() << endl;s1.clear();cout << s1.size() << endl;cout << s1.capacity()<< endl;
}

 

8,empty

仅仅判断string对象是否为空,不影响string里面的内容。

0为true,其他值为false。

六,元素存取相关函数

1,操作符重载[]

 这个函数有两种形式,第一种对于不修改字符对象内容,第二种用于修改字符对象。[]的重载,使得string类型的对象直接使用[]返回索引位置的引用。

下面来看一组例子:

void text_string7()
{string s1("ffdasfaj");cout << s1[0] << endl;s1[0] = 'g';cout << s1[0] << endl;//cout << s1[100] << endl;}

[]操作符通过返回值可以对指定位置进行修改,里面的操作数如果大于size,会显示未定义错误

2,at

at的功能和[]一致,只有在操作数大于size时,at会报out_of_range错误。 

3,back

 作用于string返回最后有效字符的引用,同样有两种类型,第一种可以修改string的内容,第二种则不可以进行修改。

来看一组例子:
 

void text_string8()
{string s1("ffdasfaj");cout << s1.back() << endl;s1.back() = 'g';cout << s1.back() << endl;
}

 可以通过引用来修改最后一个字符的值,此函数不能用于空对象,会显示未定义报错。 

4,front

返回第一个位置字符的引用 ,和begin函数相似。有两种类型,第一种可以修改string的内容,第二种则不可以进行修改。

来看一组例子:
 

void text_string9()
{string s1("ffdasfaj");cout << s1 << endl;s1.front() = 'g';cout << s1 << endl;
}

  可以通过引用来修改第一个字符的值,此函数不能用于空对象,会显示未定义报错。

七,修饰对象相关函数

1,+=运算符重载

返回string对象的引用,在string对象的尾部插入string对象,字符串,或者字符。

来看一组例子

void text_string1()
{string s1;string s2 = "fasljl";s1 += s2;cout << s1 << endl;s1 += "aaaaa";cout << s1 << endl;s1 += 'm';cout << s1 << endl;}

 

第一组实现对象之间的加等

第二组实现对象与字符串之间的加等

第三组实现对象与字符类型的加等

当容量不够时,自动进行扩容 

2,append

实现对原字符串的尾部插入,和(+=)功能相似。

第一个str表示子对象,实现子对象对原对象尾部的插入。

第二个str表示子对象,subpos表示子对象开始的位置(起点为0),sublen表示从起点开始的长度。

此函数表示将从subpos开始的位置向后sublen个长度的内容,尾插到原对象。subpos大于str长度时报out_of_range错误。

第三个s表示字符串,将字符串尾插到元对象

第四个s表示字符串,n表示起点的位置。此函数表示从起点开始的位置一直到结尾的内容尾插到原对象。

第五个n表示个数,表示字符。此函数将n个字符尾插到原对象。

来看一组例子:

void text_string2()
{string s1;string s2 = "fasljl";string s3;s1.append( s2);cout << s1 << endl;s1.append(s2, 0, 2);cout << s1 << endl;s3.append("aaaaa");cout << s3 << endl;s3.append("bbbbbbb", 3);cout << s3 << endl;s3.append(3,'p');cout << s3 << endl;}

 

第一组表示对象之间

第二组表示对象与指定对象区间之间

第三组表示对象与字符串之间

第四组表示对象与指定字符串区间之间

第五组表示对象与字符之间,注意必须要传字符个数,不支持只传入单个字符

注意:在字符串或者字符没有进行初始化操作时,都会出现抛出异常

3,push_back

尾插单个字符,此函数实现了单个字符传入 ,字符没有初始化会有抛出异常。

4,assign

注意功能就是代替原对象,分为下面五种

第一个str表示子对象,实现子对象对原对象的替换

第二个str表示子对象,subpos表示子对象开始代替的位置,sublen从开始代替的位置向后的长度。此函数表示从subpos位置开始sublen个长度的内容,代替到原对象。

第三个s表示字符串,将字符串的内容代替到原对象

第四个s表示字符串,n表示起始位置。此函数表示从起始位置开始一直到字符串结束的内容,替换到原对象。

第五个n表示字符个数,c表示字符。此函数将n个字符替换到原对象

来看一组例子

void text_string3()
{string s1 = "fsdjlkjkfsdlj";string s2 = "fasljl";string s3;s1.assign(s2);cout << s1 << endl;s1.assign(s2, 0, 2);cout << s1 << endl;s3.assign("aaaaa");cout << s3 << endl;s3.assign("bbbbbbb", 3);cout << s3 << endl;s3.assign(3, 'p');cout << s3 << endl;}

 

第一组表示对象之间的代替

第二组表示对象与指定对象区间的代替

第三组表示对象与字符串之间的代替

第四组表示对象与指定字符串区间的代替

第五组表示对象与指定个数字符之间的代替

注意:这些代替过程中,子对象,子字符串,子字符不受影响。原对象的原有数据全部被子数据代替。 

5,insert

这个函数的功能在指定位置插入数据,分为下面五个部分

第一个,pos指原对象的指定位置,str表示子对象。将子对象的数据插入到元对象指定位置之前的位置。

第二个,pos指原对象的指定位置,str表示子对象,subpos表示子对象的指定位置,sublen表示子对象的数据长度。此函数表示将子对象从subpos位置开始sublen长度的数据插入到原对象pos位置之前。

第三个,pos指原对象的指定位置,s表示字符串。将字符串传入pos位置之前。

第四个,pos指原对象的指定位置,s表示字符串,n表示起始位置。此函数表示从n开始一直到字符串结束的数据插入到pos之前。

第五个,pos指原对象的指定位置,,n表示字符个数,c表示字符。将n个字符插入到pos之前的位置。

来看一组例子:
 

void text_string4()
{string s1 = "fsdjlkjkfsdlj";string s2 = "fasljl";string s3;s1.insert(0,s2);cout << s1 << endl;s1.insert(0,s2, 0, 2);cout << s1 << endl;s3.insert(0,"aaaaa");cout << s3 << endl;s3.insert(0,"bbbbbbb", 3);cout << s3 << endl;s3.insert(0,3, 'p');cout << s3 << endl;}

 

第一组表示对象与对象之间

第二组表示对象与指定对象区间之间

第三组表示对象与字符串之间

第四组表示对象对指定区间字符串之间

第五组表示对象与n个字符之间。

注意:当指定区间超出所在字符串或者对象长度时会抛异常。 

6,erase

此函数和clear相似,erase可以进行指定位置和指定长度的删除,若长度不传参数则表示从指定位置到最后全部删除。若pos超出对象范围,则会抛异常。 

7,replace

此函数实现子数据对原对象指定区域的替换,和assign相似。 

第一个,pos指定原对象位置,len字符长度,str表示子对象。此函数表示,从pos位置开始len个数据的内容由str对象数据代替。

第二个,pos指定原对象位置,len字符长度,str表示子对象,subpos表示子对象的起始位置,sublen长度。此函数表示将子对象从subpos位置之后sublen长度的数据代替原对象从pos开始len个长度的数据。

第三个,pos指定原对象位置,len字符长度,s表示字符串,此函数表示将字符串的数据替换到原对象从pos位置开始len个长度的数据。

第四个,pos指定原对象位置,len字符长度,s表示字符串,n表示起始位置。此函数表示对子字符串从n开始位置到末尾的数据替换到原对象从pos位置开始len个字符的内容

第五个,pos指定原对象位置,len字符长度,n代表数据个数,c表示字符。此函数表示将n个字符替换到原对象从pos位置开始len个长度的内容。

下面来看一组例子

void text_string5()
{string s1 = "fsdjlkjkfsdlj";string s2 = "aaaaaaaaaa";string s3 = "llllllll";s1.replace(0, 2, s2);cout << s1 << endl;s1 = "fsdjlkjkfsdlj";s1.replace(0, 2, s2, 0, 2);cout << s1 << endl;s3.replace(0, 2, "aaaaa");cout << s3 << endl;s3 = "llllllll";s3.replace(0, 2, "bbbbbbb", 3);cout << s3 << endl;s3 = "llllllll";s3.replace(0, 3, 4, 'p');cout << s3 << endl;}

第一组表示对象与对象之间

第二组表示对象与指定对象区间之间

第三组表示对象与字符串之间

第四组表示对象对指定区间字符串之间

第五组表示对象与n个字符之间。

注意:pos和subpos当越界时会抛异常

8,swap

实现两个对象的交换 

9,pop_back

erase最后一个有效字符,当字符对象为空时,会显示未定义错误。

八,针对字符串相关函数

1,c_str

返回一个指向首字符的数组指针。 

2,get_allocator

 返回一个分配器对象的副本

3,copy

将原对象的指定内容拷贝到s数组中,pos指原对象的位置,len指拷贝长度

来看一组例子

void text_string6()
{string s1 = "fsdjlkjkfsdlj";char arr[100]= "0";cout << s1.copy(arr,2,0) << endl;cout << arr << endl;}

 

相当于从原对象指定内容拷贝到数组中

 

4,find

数据与原对象的匹配函数,匹配成功返回数据的下标

第一个,str子对象,pos指开始匹配的的位置。此函数表示从pos位置开始和子对象进行匹配

第二个,s字符串,pos指开始匹配的位置。此函数表示从pos位置开始和字符串进行匹配

第三个,s字符串,pos指开始匹配的位置,n字符串需要匹配的长度。此函数表示从pos位置开始匹配,匹配字符串前n个数据。

第四个,pos位置开始匹配匹配c字符。

来看一组例子

void text_string7()
{string s1 = "fsdjlkjkfsdlj";string s2 = "jlk";cout << s1.find(s2,0) << endl;cout << s1.find(s2, 3) << endl;cout << s1.find(s2, 4) << endl;cout << s1.find("sdj", 0) << endl;cout << s1.find("sdj", 3) << endl;cout << s1.find("sdj", 3,1) << endl;cout << s1.find('j', 4) << endl;
}

 

第一组匹配成功返回下标3 

第二组匹配成功返回下标3

第三组匹配失败返回 npos

第四组匹配成功返回下标1

第五组匹配失败返回 npos

第六组匹配成功返回下标9,这匹配一个字符s

第七组匹配成功返回下标6

5,rfind

倒着查找,pos表示查找范围为pos以及pos之前,其余参数都和find一致 

6,find_first_of

当匹配数据的第一个数据匹配成功就算成功,参数和find一致 

7,find_last_of

 当匹配数据的最后一个有效数据匹配成功就算成功,参数和rfind一致 

8,substr

构造一个新的对象,将原对象的指定数据拷贝的新构造的数据,pos指开始的位置,len指拷贝长度。 

来看一组例子:

void text_string8()
{string s1 = "fsdjlkjkfsdlj";cout << s1.substr(0, 3) << endl;cout << s1.substr(0) << endl;cout << s1.substr(4) << endl;}

此函数生成一个临时对象。 

9,compare

比较原对象和子对象,子字符串。pos,len修饰原对象,分别代表起始位置和跨越长度。subpos,和sublen,修饰子对象 ,分别代表起始位置和跨越长度。n表示子字符串开始比较的起始位置。

九,全局函数

1,+运算符重载

两个类型相加,构造出一个新的string对象,该对象为临时对象 

2,>>运算符重载

可以输入string类型的变量 

3,<<运算符重载

可以输出string类型的对象 

4,getline

向比较于>>此函数遇到空格不停止读入,遇到换行结束。 

十,总结

有几个重要的接口(size,resize,reserve,=,+=,empty,clear,getline,find)需要熟悉掌握,其他的接口注意进行了解,当需要的时候可以通过查文档的方式进行了解如何去使用。

相关文章:

  • SAP-ABAP:企业级异常处理框架设计与实战 —— 构建高可用、可观测的异常治理体系
  • linux 学习之位图(bitmap)数据结构
  • Leetcode-2 最小偶倍数
  • Leetcode-3 判断根结点是否等于子结点之和
  • 【专四 | 2022年真题】LANGUAGE USAGE逐题总结
  • SpringBoot微服务编写Dockerfile流程及问题汇总
  • day32 python解释性库PDPbox
  • 差分数组 - 对区间内元素的统一操作
  • Coze工作流-选择器的用法
  • LangChain入门和应用#1
  • COMPUTEX 2025 | 广和通5G AI MiFi解决方案助力移动宽带终端迈向AI新未来
  • 【java第19集】java面向对象编程详解
  • k8s-NetworkPolicy
  • Datawhale 5月llm-universe 第4次笔记
  • 【题解-洛谷】P6180 [USACO15DEC] Breed Counting S
  • docker面试题(4)
  • Win11上安装docker
  • 深度学习+Flask 打包一个AI模型接口并部署上线
  • 系统架构设计师案例分析题——数据库缓存篇
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.4.9)
  • 特朗普集团在越南开建度假村,探讨在胡志明市建摩天大楼
  • 深一度|有望冲击首轮秀?杨瀚森走出舒适圈站上大舞台
  • 建行原副行长章更生涉嫌受贿罪、违法发放贷款罪被逮捕
  • “除非我去世”,马斯克称仍致力于继续执掌特斯拉
  • 中国社科院国际合作局副局长廖凡调任世界经济与政治研究所所长
  • 长三角哪些城市爱花钱?这个城市令人意外