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

C++:string 类

目录

一、STL

1.1、STL的基本概念

1.2、STL的六大组件

1.2.1、容器

1.2.2、算法

1.2.3、迭代器

1.2.4、仿函数

1.2.5、适配器

1.2.6、分配器

二、string 类的简单介绍

三、string类的常用操作详解

3.1、构造和初始化

3.1.1、string()

3.1.2、string(const string& str)

3.1.3、string(const string& str, size_t pos, size_t len = npos)

3.1.4、string (const char* s)

3.1.5、string(const char* s, size_t n)

3.1.6、string(size_t n,  char c)

3.2、string 的析构函数

3.3、赋值符重载

3.4、string类的迭代器

3.4.1、begin

3.4.2、end

3.4.3、rbegin 和 rend

3.4.4、cbegin ,cend, crbegin, crend

3.5、stirng 类的容器

3.5.1、size 和 length

3.5.2、max_size

3.5.3、resize 和 capacity

3.5.4、reserve

3.5.5、clear

3.5.6、empty

3.5.7、shrink_to_fit

3.6、string类的元素访问

3.6.1、operator[ ]

3.6.2、at

3.6.3、back

3.6.4、front

3.7、string类的修改器

3.7.1、append

(1)string& append(const string& str)

(2)string& append(const string& str, size_t subpos, size_t sublen)

(3)string& append(const char* s)

(4)string& append(const char* s , size_t n)

(5)string& append(size_t n , char c)

3.7.3、operator+=

3.7.5、insert

3.7.6、erase

3.7.7、replace

3.7.8、swap

3.7.9、pop_back

3.8.1、c_str 和 data

3.8.2、copy

3.8.3、find

3.8.4、rfind

3.9、npos

3.10、getline

四、练习与巩固

4.1、字符串相加

4.2、翻转字符串中的单词


一、STL

1.1、STL的基本概念

        STL ,全名标准模板库,不仅是一个可以重复使用的组件库,而且是一个包罗数据结构与算法的软件框架。

        说人话,STL 就是 C++自己带的一个工具箱,里面提供了已经写好的数据结构和算法

1.2、STL的六大组件

STL 的六大组件(六大组成部分)为:容器,算法,迭代器,仿函数,适配器,分配器。

1.2.1、容器

        作用:负责数据的存储和管理,封装了底层数据结构。

        说人话,容器就是STL提供的多种箱子,用来存放不同的数据。每种箱子都有自己的特性和适用场景。

1.2.2、算法

        作用:对容器中的数据进行各种操作和处理

        特点:算法通过迭代器与容器交互,不依赖容器具体类型

1.2.3、迭代器

        作用:提供一种统一的方法来遍历和访问容器中的元素

        通俗一点,迭代器就像一个导游,带领算法访问容器中的元素

        重要性:实现了容器与算法的分离,是泛型编程的关键

1.2.4、仿函数

        作用:让对象具有函数的行为,增加算法的灵活性

1.2.5、适配器

        作用:改变组件的接口,使其适应不同的场景

1.2.6、分配器

        作用:封装内存管理的细节,为容器分配和释放内存

二、string 类的简单介绍

        string类用来管理程序中的字符串,出现的时间比STL要早,SLT很多内容都是参考的string,后面STL成熟了,string也有些内容是参考STL修改的。

        在C语言中,用数组存放字符串,我们需要担心是否越界,需要手动扩容和释放。但在C++中,我们有string类,它可以帮助我们完成这些事情,节省程序员的精力。

        使用string类是需要头文件的: <string> ,同时也是有命名空间的 :std

三、string类的常用操作详解

3.1、构造和初始化

string的构造初始化一共有以下几种:

3.1.1、string()

这就是最原始的构造函数。举个栗子:

string s1;
cout << s1 << endl;

        这里的 s1 放的是一个空字符 \0 ,打印出来就是什么也没有。其次,string类是有对 << 重载的,因此可以直接用 cout 打印

3.1.2、string(const string& str)

这是拷贝构造函数,举个例子:

string s2(s1);
string s3 = s1;

这两者都是拷贝构造调用的形式。

3.1.3、string(const string& str, size_t pos, size_t len = npos)

对str这个字符串,从位置pos开始到npos结束的这段字符复制,然后拷贝到新的字符串。例如:

string s1("Hello World!");
string s2(s1, 2, 5);
cout << s1 << endl;
cout << s2 << endl;

结果为:

注意:可以看到,从位置 2 到 5为止 拷贝,最后实际执行的是下标为 2 到下标为 6 的地方!(这与空白字符无关,实际上将空白字符用别的字符代替,最后还是会打印到w)

3.1.4、string (const char* s)

复制由字符指针指向的以空字符结尾的字符串序列。说人话,就是把char* 指向的字符串拷贝到新字符串中。举例:

char ch1[] = "Hello World!";
string s2(ch1);
cout << ch1 << endl;
cout << s2 << endl;

3.1.5、string(const char* s, size_t n)

就是把 s 指向的字符串,赋值前 n 个字符。举例:

char ch1[] = "Hello World!";
string s2(ch1, 7);
cout << ch1 << endl;
cout << s2 << endl;

3.1.6、string(size_t n,  char c)

用字符 c 填充新字符串,共填充 n 次。举例:

string s1(10, '#');
cout << s1 << endl;

3.2、string 的析构函数

~string();

这个就是析构函数,没什么好说的,跳过。

3.3、赋值符重载

非常简单,直接举例:

string s1("Hello World!");
string s2;
s2 = s1;
cout << s2 << endl;
char ch1 = '%';
s2 = ch1;
cout << s2 << endl;
char ch2[] = "Hello CPlusPlus";
s2 = ch2;
cout << s2 << endl;

3.4、string类的迭代器

如图是string的迭代器大全:

迭代器是引领算法访问容量的,相当于一个指针。

3.4.1、begin

作用:返回指向字符串的第一个字符的迭代器。

例如:我现在要访问字符串的第一个字符,就可以这样:

string str = "Hello World!";
string::iterator it = str.begin();
cout << *it << endl;

注意:iterator 不是C++的关键字,而是定义在容器内部的一个指针类型别名。它的中文意思就是迭代器。iterator 在string类的内部实际上是一个 char* 类型的别名。

3.4.2、end

作用:返回字符串的最后一个字符的下一个位置,也就是 /0。因此对该迭代器进行解引用是十分危险的。大部分使用这个迭代器是为了划定字符串的边界,例如:

string s1 = "Hello World!";
string::iterator it2 = s1.end();
string::iterator it1 = s1.begin():
while(it1 != it2)
{cout << "hehe" << endl;
}

3.4.3、rbegin 和 rend

这两个迭代器的作用是从后往前遍历字符串,取第一个字符的地址和最后一个字符的地址。从原型中可以看出,这两个迭代器的类型为:reverse_iterator 。下面举个例子:

string s1 = "abcedefg";
string::reverse_iterator rbegin1 = s1.rbegin();
string::reverse_iterator rend1 = s1.rend();
cout << *rbegin1 << endl;
//cout << *rend1 << endl;

rend 指向的是字符串第一个字符的前一个位置,通常被记为 \0 ,因此不能解引用。此外,reverse_iterator 也是一种 char* 类型的别名。

3.4.4、cbegin ,cend, crbegin, crend

这几个都是前面讲的const版本(前面加了一个c),返回的类型该是iterator 还是 reverse iterator没有任何变化,对于返回的迭代器,也可以进行正常的加减操作,但是,迭代器所指向的内容是不可以被更改的!

3.5、stirng 类的容器

3.5.1、size 和 length

size 和 length都是返回字符串长度的(不带最后的斜杠0),有两个名字 size 和 length 纯粹是有些结构可以用大小来说,有些结构只能用长度来说。举例:

string s1 = "Hello World!";
cout << s1.size() << endl;

最后结果为12。

3.5.2、max_size

功能:返回字符串所能达到的最大长度。(注意是能达到的最大长度,而不是字符串现在的最大长度)

这个在实际中不怎么使用。

3.5.3、resize 和 capacity

resize:将字符串的字符个数改为 n 个(不包含斜杠0),多出来的空间用字符 c 填充。但该操作不会影响字符串的容量。例如:

string s1 = "Hello World!";
cout << s1 << endl;
s1.resize(20, '#');
cout << s1 << endl;

那如果你用resize设置的字符个数比原本的就小呢?那字符串的个数就缩小到你设置的个数(不包含斜杠0)。

capacity:返回已分配空间的大小。注意,是已分配空间的大小,而不是字符串的大小!例如:

string s1 = "a";
cout << "s1.capacity:" << s1.capacity() << endl;
string s2 = "Hello World";
cout << "s2.capacity:" << s2.capacity() << endl;
string s3 = "Hello World! Hello World!";
cout << "s3.capacity:" << s3.capacity() << endl;

结果为:15  ,15,  31

3.5.4、reserve

给字符串扩容,扩容后的字符串的容量至少为 n ,例如:

string s1 = "Hello World!";
cout << "扩容前:" << s1.capacity() << endl;
s1.reserve(20);
cout << "扩容后:" << s1.capacity() << endl;

答案为:15  ,  31

那如果扩容给的 n 小于当前字符串的容量呢?这个不确定,根据编译器而定,不过一般都不会缩容的,而是保持现有容量不变。

3.5.5、clear

作用:清空一个字符串,使其变为空字符串。但是字符串的容量不变。

3.5.6、empty

作用:判断字符串是否为空,字符串为空,返回true,否则返回false

3.5.7、shrink_to_fit

作用:就是给字符串缩容。只会将字符串的容量缩小至目前所需的最小容量。例如,存放10个字符的字符串,但是容量为31,使用该函数后,容量只会缩小至15!

3.6、string类的元素访问

3.6.1、operator[ ]

有非const和const两个版本。

就是像访问数组的元素那样去访问字符串里的字符,同样,第一个字符的下标为0。例如:

string s1 = "abcdefgh";
cout << s1 << endl;
for (int i = 0; i < s1.size(); i++)
{s1[i] += 1;
}
cout << s1 << endl;

3.6.2、at

作用:返回字符串当前位置的的字符。例如:

string s1 = "abcdefgh";
cout << s1.at(2) << endl;

答案为:c

3.6.3、back

作用:范回字符串的最后一个字符的引用。例如:

string s1 = "abcdefgh";
cout << s1.back() << endl;

最后结果为: h

如果对空字符串使用back会报错!

3.6.4、front

作用:返回字符串第一个字符的引用。例如:

string s1 = "Hello World!";
s1.front() += 1;
cout << s1 << endl;

结果为:Iello World!

如果对空字符串使用会报错!

3.7、string类的修改器

3.7.1、append

(1)string& append(const string& str)

作用:在字符串后面再添加一个字符串。例如:

string s1 = "Hello World!";
string s2 = "Hello Cplusplus";
s1.append(s2);
cout << s1 << endl;

(2)string& append(const string& str, size_t subpos, size_t sublen)

作用:将第二个字符串的指定区间添加到第一个字符串的末尾。例如:

string s1 = "Hello World!";
string s2 = "Hello Cplusplus";
s1.append(s2 ,2,4);
cout << s1 << endl;

(3)string& append(const char* s)

就是把 s 指向的字符串添加到源字符串末尾。与第一个一样,只不过一个是string类型,一个是char*类型。

(4)string& append(const char* s , size_t n)

把 s 指向的字符串的前 n 个字符放到源字符串的末尾。例如:

string s1 = "Hello World!";
char ch1[] = "abcdef";
s1.append(ch1, 3);
cout << s1 << endl;

(5)string& append(size_t n , char c)

作用:在原字符串末尾添加 n 个字符 c。例如:

string s1 = "Hello World!";
s1.append(3 ,'#');
cout << s1 << endl;

3.7.2、push_back

作用:将字符 c 添加到字符串末尾。例如:

string s1 = "Hello World!";
s1.push_back('$');
cout << s1 << endl;

3.7.3、operator+=

作用:在字符串末尾添加字符,字符串。

在实际编程中,有了+=重载,append用的就非常少了,因为+=实在是太方便了。

string s1 = "Hello World!";
s1 += "abcdef";
cout << s1 << endl;

    

3.7.4、assign

作用:原字符串替换成参数里的字符串。例如:

string s1 = "Hello World!";
string s2 = "abcdefg";
cout << s1 << endl;
s1.assign(s2);
cout << s1 << endl;

3.7.5、insert

作用:在原字符串的指定位置添加字符串。例如:

string s1 = "Hello World!";
cout << s1 << endl;
s1.insert(2, "#");
cout << s1 << endl;

3.7.6、erase

作用:从字符串中删除某些字符。例如:

string s1 = "Hello World!";
cout << s1 << endl;
s1.erase(2, 5);
cout << s1 << endl;

3.7.7、replace

作用:将字符串从pos开始,len 个字符替换为新的字符串。例如:

string s1 = "Hello World!";
string s2 = "hahahehe";
s1.replace(2, 5, s2);
cout << s1 << endl;

3.7.8、swap

作用:将容器中的内容替换为该字符串中的内容。包括容量。

string s1 = "Hello World!";
string s2 = "hahahehe";
s2.reserve(30);
cout << s1 << " " << s1.size() << " " << s1.capacity() << endl;
s1.swap(s2);
cout << s1 << " " << s1.size() << " " << s1.capacity() << endl;

3.7.9、pop_back

作用:删除字符串的最后一个字符。不能对空字符串使用!例如:

string s1 = "Hello World!";
cout << s1 << endl;
s1.pop_back();
cout << s1 << endl;

3.8、string类的字符串操作

3.8.1、c_str 和 data

作用:返回一个C字风格类型的字符串。是将string类型转变为char*类型的桥梁。唯一不同的是c_str 转换后末尾一定是有斜杠0的,而data就不一定了。但是注意,转变成char*以后得字符串只可读不可写!举例:

string s1 = "Hello World!";
const char* ch1 = s1.c_str();
cout << ch1 << endl;

多用于使用C语言中的某些函数传参时必须使用 char* 类型的情况。

string filename = "example.txt";
// 使用C库函数需要C风格字符串
FILE* file = fopen(filename.c_str(), "r");

3.8.2、copy

作用:将源字符串从pos开始到len个字符复制到 s 指向的字符串中。注意,第一个参数为接收被复制字符的对象,第二个参数为复制字符的个数,第三个参数为被复制字符在原字符串的起点。例如:

char ch1[20] = { 0 };
string s1 = "123456789";
s1.copy(ch1, 3, 1);
cout << ch1 << endl;
cout << s1 << endl;

3.8.3、find

作用:在字符串中查找其参数指定的序列首次出现的位置。第一个参数为要查找的字符串,第二个参数为被查找字符串的查找起点。例如:

string s1 = "hello world!+hello world!";
string s2 = "hello world!";
cout << s1.find(s2) << endl;
cout << s1.find(s2 , 5) << endl;

答案为: 0   , 13

3.8.4、rfind

作用:在字符串中查找参数指定序列最后一次出现的位置。第一个参数为被查找序列,第二个参数为查找该位置之前的字符串。该函数与find刚好相反,find从前往后查找第一出现的,rfind从后往前查找,找最后一次出现的。

3.9、npos

npos 是string类的一个静态成员变量,类型为: size_t 。

size_t 类型为非负数的类型,但是 npos的赋值为 -1 ,根据数据溢出原则,npos 将会是这个类型能放下的最大正数。所以,npos 在string类代表着一个很大的数字,含义是:直至字符串末尾。

3.10、getline

对于输入一串含有空格字符的字符串,使用传统的 cin 会在遇见空格字符就收手。但是,getline只会遇见回车符才会收手,完美的解决了含有空格字符的输入问题。

此外,getline 还可以只能收手的字符。

string s1;
getline(std::cin , s1);
cout << s1 << endl;

四、练习与巩固

4.1、字符串相加

415. 字符串相加 - 力扣(LeetCode)

在处理很大的数据的时候,int,long long 类型就不够看了,这两个能够存放的整型位数不过 9 位和18位,很容易就溢出,但是采用字符串就不一样了,没有上限。这道题就是用两个字符串来表示两个整型的加法的。其细节内容和我们小学的列竖式一样。

string addStrings(string num1, string num2) {int end1 = num1.size()-1;int end2 = num2.size()-1;int carry = 0;string returnret;while( end1 >= 0 || end2 >= 0){int value1 = end1 >= 0? num1[end1] - '0' : 0;int value2 = end2 >= 0? num2[end2] - '0' : 0;end1--;end2--;int ret = value1 + value2 + carry;carry = ret/10;ret = ret % 10;//头插returnret.insert(0 ,1, ret+'0');}if(carry != 0){returnret.insert(0 ,1, carry+'0');}return returnret;}

4.2、翻转字符串中的单词

https://leetcode.cn/problems/reverse-words-in-a-string-iii/

思路:先写一个函数,用于交换字符串特定范围内的逆置。然后在寻找空格字符,每找到一个空格字符就进行一次范围逆置。最后不要忘了把最后一部分的单词单独逆置。

//翻转函数void reversestr(string& s ,int left ,int right){while(left <= right){swap(s[left] ,s[right]);left++;right--;}}string reverseWords(string& s) {//寻找空字符size_t left = 0, right = 0;right = s.find(" ");while(right < s.size()){reversestr(s,left ,right-1);left = right+1;right = s.find(" " , left);}reversestr(s,left ,s.size()-1);return s;}

http://www.dtcms.com/a/446544.html

相关文章:

  • [crackme]019-CrackMe3
  • 宠物寄养网站毕业设计营销网站建设专业团队在线服务
  • C++11学习笔记
  • 搜狐快速建站郴州市做网站
  • 在Linux中重定向,复制cp,硬链接的区别,Linux底层存储数据原理。
  • 软考~系统规划与管理师考试—知识篇—V2.0—考试科目2:系统规划与管理案例分析—题型分类—第七章 IT 服务持续改进—20192021
  • NopGraphQL 的设计创新:从 API 协议到通用信息操作引擎
  • 概率论:分布与检验
  • 网站后台视频教程视频号怎么付费推广
  • 浦江网站建设微信开发wordpress 浏览计数
  • 嵌入式开发学习日志35——stm32之超声波测距
  • 山东建设厅官方网站一级建造师搜索引擎平台
  • MATLAB计算有效干旱指数(Effective drought index, EDI)
  • 网站推广如何收费现在建一个网站一年费用只要几百元
  • 如何自己做游戏网站如何建设万网网站
  • 江苏省建设厅八大员考试报名网站石家庄有哪些公司可以做网站
  • 搭建Jenkins gitlab 环境
  • 企业做的网站费入什么科目江西网站备案
  • pink老师html5+css3day05
  • 哪里找人做网站织梦淘客网站
  • 网站开发原型法装个宽带多少钱
  • BTS7960 四轮运动控制 可行 前后左右
  • Linux学习笔记--i2c_Adapter驱动框架
  • 新乡做网站建设工程网站有哪些
  • liferay 做网站仿wordpress站
  • MySQL 中一条 SQL 语句的执行流程
  • 2025年--Lc162--H169.多数元素(数组和字符串)--Java版
  • wordpress搭建个人网站蚌埠市建设工程质监站网站
  • 中国建设銀行网站投诉电话wordpress 钩子列表
  • 腾讯云微服务平台TSF