C++:string的介绍

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合面向对象的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

所以在C++的STL库中提供了更加方便的string类。


string

string的常见构造

默认构造函数:string()

  • 创建一个空字符串对象。
  • 示例:
string str;

拷贝构造函数:string(const string& str)

  • 创建一个字符串对象,内容为另一个字符串对象str的拷贝。
  • 示例:
 string str1("hello");string str2(str1); // "hello"

重载构造函数:string(const string& str, size_t pos, size_t len = npos)

  • 创建一个字符串对象,内容为字符串对象str的pos位置开始的len个字符。
  • 示例:
  •  string str1("hello"); string str2(str1, 1, 3); // "ell:
  • 注意:当不传入第三个参数时,其默认为npos,这个值是size_t的最大储存值,可以理解为是无穷大,也就是说,当不传入第三个参数,其会从pos位置开始拷贝到结束。

重载构造函数:string(const char* s)

  • 创建一个字符串对象,内容为字符串s
  • 示例:
  • string str("hello");
    
  • 由于单参数构造函数支持类型转换,也可以写为:
    string str = "hello";

重载构造函数:string(const char* s, size_t n)

  • 创建一个字符串对象,内容为字符串s的前n个字符。
  • 示例:
string str("hello", 3); //"hel"

重载构造函数:string(size_t n, char c)

  • 创建一个由n个字符c组成的字符串对象。
  • 示例:
string str(5, 'a'); // "aaaaa"

string的输入输出
operator<<

string<<进行了重载,我们可以直接对string对象使用<<,此时会输出这个string对象的字符串值。

示例:

string s1 = "hello world";
string s2 = " csdn";cout << s1 << endl; //"hello world"
cout << s1 << s2 << endl; //"hello world csdn"
c_str

string还提供了一个函数,用于读取string对象中的字符串。

string s = "hello world";
cout << s.c_str() << endl; // "hello world"

c_str的返回值是一个字符串,而<<对于字符串的输出机制是遇到'\0'中止输出。而string类重载的<<输出机制则是完整输出整个字符串,如果遇到'\0',会把'\0'一起输出。 

 看一个案例:

string s = "hello world \0 csdn";
cout << s.c_str() << endl; // "hello world "
cout << s << endl; // "hello world 0 csdn"
operator>>

同样的,string也对>>进行了重载,我们可以使用>>输入字符串。

string s1;
string s2;cin >> s1 >> s2; // 输入"hello world"
cout << s1 << endl; // "hello"
cout << s2 << endl; // "world"

但是如果我们输入的字符串中包含空格,那么>>就不是很好用。

由于输入字符串时,遇到空格会中止读取,所以包含空格的字符串不能用这个方式输入,此时就要用getline了. 

getline

getline可以获取一整行的字符串,包括空格,只有遇到换行符的时候才会中止。
不过要注意getline不是string类的成员函数,但是是string头文件的普通函数。
所以使用时不需要使用对象.getline()这样的格式,而是直接使用。

其第一个参数是istream的对象,比如cin
第二个参数是输入到的string对象。
第三个参数决定遇到什么字符的时候停止读取,默认值为'\n',即换行时停止读取。

示例:

string s;getline(cin, s); // "hello world csdn"
cout << s << endl; // "hello world csdn"

string访问及遍历
operator[ ] & at

operator[ ] 和 at都是通过下标访问的成员函数,两者作用几乎一致。

示例:

string s = "hello world";cout << s[2] << endl; // 'l'
cout << s[8] << endl; // 'r'

 示例:

string s = "hello world";cout << s.at(2) << endl; // 'l'
cout << s.at(8) << endl; // 'r'

两者的参数完全一致,即pos下标,传入这个参数后,输出下标位置的字符。此外,他们各自都提供了const版本的重构,用于const对象。
两者唯一的区别就是越界的情况:
operator[ ]越界时,会通过assert报错,直接中止程序。
at越界时,会抛出异常。 

font & back

font 和 back用于返回字符串的首尾字符。

要注意,其返回值为引用返回char&,所以对其修改时,是会影响到原先的字符串的。


如果我们想遍历一个字符串,可以通过operator[ ] 或者 at,利用for循环来遍历,但是STL库还提供了迭代器,用于遍历对象。

迭代器
begin & end

在C++的string类中,beginend是两个成员函数,用于返回字符串的起始和结束迭代器。

 begin函数返回一个迭代器,该迭代器指向字符串的第一个字符。可以使用解引用运算符*获取迭代器指向的字符。例如,*str.begin()将返回字符串中的第一个字符。

 end函数返回一个迭代器,该迭代器指向字符串结尾的下一个位置。因此end()函数返回的迭代器不指向字符串中的任何字符。可以将end函数返回的迭代器与其他迭代器进行比较,以确定迭代器是否已达到字符串的末尾。

演示如何使用beginend函数遍历字符串中的字符并输出它们:

string str = "Hello World";// 使用begin()和end()函数遍历字符串中的字符
string::iterrtor it = str.begin()
while(it != str.end())
{cout << *it;++it;
}

平常可以直接用auto来代替这个类型。

所以以上代码可以写为:

string str = "Hello World";// 使用begin()和end()函数遍历字符串中的字符
auto it = str.begin()
while(it != str.end())
{cout << *it;++it;
}

rbegin & rend

迭代器不仅支持正向遍历,还支持反向遍历,此时就需要反向迭代器rbegin,rend了。其中r代表reverse,反转的意思。

 rbegin是一个反向迭代器,用于指向容器的最后一个元素,并向前迭代。rendrbegin的逆操作。rbegin返回容器的最后一个元素的迭代器,而rend返回容器的第一个元素之前的位置的迭代器,这是一个越界的位置,同样不允许修改。

string s1 = "54321";string:reverse_iterator rit = s.begin();while (rit != str.rend()) {cout << *rit << " ";++rit;
}
范围for

范围for循环也适用于string,其本质是基于迭代器的循环。

string s = "hello world";for(auto ch : s)
{cout << ch;
}

string的容量操作
size & length&capacity

size返回当前字符串的长度。

length返回当前字符串的长度。

capacity函数用于返回字符串的当前容量(当前可以存储的最大字符数)。

两者的作用完全一致,没有区别,那么为什么STL要设计两种方式来返回string对象的长度呢?

这是因为早期的string还不属于STL,使用length来表达长度,当string进入STL后,为了与其他的数据结构保持一致,都使用size来表示长度,于是又增加了一个size。

clear&empty

在string类中,clear函数用于清空字符串内容,并将字符串的长度设置为0。

empty函数用于检查一个字符串是否为空,即字符串中是否没有任何字符。该函数返回一个bool类型的值。

reserve

 reserve是一个用来预留字符串容量的方法。

reserve方法的目的是为了避免频繁的内存分配和释放操作,提高程序的效率。当我们使用string对象时,由于字符串的长度是可变的,所以在进行增删改等操作时,可能会导致内存重新分配,这会带来一定的时间开销。

为了避免这种情况,我们可以使用reserve方法来预先分配足够的内存空间。                     

resize

resize函数用于改变字符串的大小。它可以增加或减少字符串的长度。

resize函数有两个参数,第一个参数是新的字符串长度,第二个参数是填充字符(可选)。

如果新的长度小于当前长度,则字符串会被截断。如果新的长度大于当前长度,则字符串会自动增加大小,并用指定的填充字符填充空白部分,如果没有选定字符,则默认用\0填充。

 要注意的是,就算使用resizesize缩小,capacity容量大小不会减小,而是保持原本的大小。


string的修改操作
push_back

push_back函数用于将字符添加到字符串的末尾。它接受一个字符作为参数,并将其追加到字符串的末尾。

注意:push_back函数只接受一个字符作为参数,如果传递一个字符串或其他类型的参数,将会引发编译错误。

append

string类中的append方法用于将一个字符串追加到另一个字符串的末尾。它有多个重载版本,可以接受不同类型的参数作为输入。

基本使用:

string str1 = "Hello";
string str2 = " World!";// 使用append方法将str2追加到str1的末尾
str1.append(str2);cout << str1 << endl;  // 输出 "Hello World!"

append方法还可以接受其他类型的参数作为输入,例如const char*charstd::stringstd::initializer_list<char>等。 

 

operator+=

operator+=是用于将一个字符串追加到另一个字符串的末尾的运算符重载。

根据其三个重载可以看出来,operator+=可以追加string对象,字符串,字符三种类型,功能全面,语法简单,比appendpush_back好用的多。

insert

insert函数可以用于在字符串中插入字符、子串或其他类型的数据。

通过函数重载可以看出,我们可以插入字符,字符串,string对象等。

插入字符串:

string str = "Hello, world!";// 在指定位置插入字符串
str.insert(5, "!!!"); // 在位置5插入"!!!"
cout << str << endl;

输出结果为:Hello!!!, world!

 插入字符:

string str = "Hello, world!";// 在指定位置插入字符串
str.insert(5, 3, '!'); // 在位置5插入3个'!'
cout << str << endl;

输出结果为:Hello!!!, world!

 注意:插入字符时,第二个参数是插入字符的个数,哪怕只插入一个字符,这个值也不能缺省

erase

erase函数可以用来删除字符串中的字符或子字符串。 

首先,我们来看一个简单的示例,删除字符串中的一个字符:

string str = "Hello World";
str.erase(4); // 删除第5个字符,即空格
cout << str << endl; // 输出 "HelloWorld"

删除字符串中的一个子字符串:

string str = "Hello World";
str.erase(6, 5); // 从第7个字符开始,删除5个字符,即"World"
cout << str << endl; // 输出 "Hello"

除了上述两种用法外,erase函数还可以接受迭代器作为参数,用来删除指定范围内的字符或子字符串。

string str = "Hello World";
string::iterator start = str.begin() + 6; // 第7个字符的迭代器
string::iterator end = str.begin() + 11; // 第12个字符的迭代器
str.erase(start, end); // 删除从第7个字符到第12个字符的子字符串,即"World"
cout << str << endl; // 输出 "Hello "

replace

replace函数用于在字符串中替换指定的子字符串。

string str = "Hello, World!";cout << "原始字符串: " << str << endl;// 使用replace函数替换字符串
str.replace(str.find("World"), 5, "Universe");cout << "替换后的字符串: " << str << endl;

输出结果应为:

原始字符串: Hello, World!
替换后的字符串: Hello, Universe!

swap

swap函数用于交换两个string对象之间的内容。

string str1 = "Hello";
string str2 = "World";str1.swap(str2);cout << "After swap:" << endl;
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;

std中的swap()函数:

string str1 = "Hello";
string str2 = "World";swap(str1, str2);cout << "After swap:" << std::endl;
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;

在这个例子中,我们使用了std命名空间中的swap函数,将str1str2的内容进行了交换。输出的结果与前一个例子是一样的。

但是std中的swap将两个对象完全交换了,这个过程创建了string类型的中间变量。

 而string中的swap并没有完全交换对象,只是交换了两个对象的指针,以及值,并没有创建string类型的中间变量。所以对于string对象,使用string自带的swap效率会更高。


string的查找操作
find

find函数用于在字符串中查找子字符串的第一次出现。

find函数接受两个参数:
待查找的子字符串 str 或者字符c
开始搜索的位置 pos(可选,默认值为0)                        

返回值:

  • 如果找到了指定子串,返回它在原字符串中第一次出现的位置。
  • 如果未找到指定子串,返回string::npos
string str = "Hello World";
string subStr = "World";// 使用find函数查找子字符串的位置
size_t index = str.find(subStr);cout << "子字符串在位置 " << index << " 处被找到" << endl;
refind

rfind用于在字符串中寻找指定子串的最后一次出现的位置,或者说是倒着查找。

rfind函数接受两个参数:
待查找的子字符串 str 或者字符c
开始搜索的位置 pos(可选,默认为string::npos

返回值:

  • 如果找到了指定子串,返回它在原字符串中最后一次出现的位置。
  • 如果未找到指定子串,返回string::npos
sub_str

substr用于提取字符串的子串。该函数可以接受两个参数,起始索引位置和子串的长度。

string str = "Hello, world!";// 提取从索引位置3开始的子串
string sub1 = str.substr(3);// 输出子串
cout << sub1 << endl; // 输出为 "lo, world!"// 提取从索引位置7开始长度为5的子串
std::string sub2 = str.substr(7, 5);// 输出子串
cout << sub2 << endl; // 输出为 "world"

 输出结果为:

lo, world!
world

可以看到,substr() 函数成功提取了指定位置和长度的子串,并将其存储在新的字符串变量中。

find_first_of & find_first_not_of

find_first_of函数用于在字符串中查找第一个与指定字符序列中的任意字符匹配的字符的位置。

 find_first_of函数有多个重载形式,其中最常用的形式如下:

size_t find_first_of (const string& str, size_t pos = 0) const;

这个函数接受一个字符串参数str,并从指定的位置pos开始搜索。find_first_of函数会在调用对象的字符串中查找第一个与str中的任意字符匹配的字符,并返回其位置。如果找不到匹配的字符,则返回string::npos

string str = "Hello World";
string chars = "aeiou";// 在str中查找第一个出现在"aeiou"中的字符
size_t pos = str.find_first_of(chars);cout << "第一个元音字母出现在位置:" << pos << endl;
cout << "字符为:" << str[pos] << endl;

输出结果为:

第一个元音字母出现在位置:1
字符为:e

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/729779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈去耦电容的作用、选择、布局及其它电容的区别!

在一些文章资料中&#xff0c;去耦电容器被认为是旁路电容器。在其他资料中&#xff0c;去耦电容和旁路电容的区别在于&#xff1a;“旁路电容以输入信号中的干扰为滤波对象&#xff0c;而去耦电容以输出信号的干扰为滤波对象&#xff0c;防止干扰信号返回到输出端。”力量。”…

基于Java的生活废品回收系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&资源品类模块3.3 回收机构模块3.4 资源求购/出售/交易单模块3.5 客服咨询模块 四、免责说明 一、摘要 1.1 项目介绍 生活废品回收系统是可持续发展的解决方案&#xff0c;旨在鼓…

如何远程访问电脑文件?

远程访问电脑文件是当今数字化时代中十分常见且实用的技术。它允许我们从任何地方的计算机或移动设备访问和操作我们的电脑中的文件。无论是远程工作、远程学习、远程协作还是方便地获得自己计算机上的重要文件&#xff0c;远程访问电脑文件都为我们提供了巨大的便利。 在远程访…

【C++】stack/queue

链表完了之后就是我们的栈和队列了&#xff0c;当然我们的STL中也有实现&#xff0c;下面我们先来看一下简单用法&#xff0c;跟我们之前C语言实现的一样&#xff0c;stack和queue有这么几个重要的成员函数 最主要的就是这么几个&#xff1a;empty&#xff0c;push&#xff0c;…

LeetCode-91题:解码方法(原创)

【题目描述】 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; A -> "1" B -> "2" ... Z -> "26" 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可能有多种…

如何获取国外信用卡?需要国外银行卡支付怎么解决?如何订阅国外产品?

当国内的用户想要使用国外的产品时&#xff0c;很多产品是需要订阅付费的。其中有些产品还没有引入国内&#xff0c;只能用国外的信用卡支付&#xff0c;对于在国内的朋友&#xff0c;如何获取一张国外的信用卡呢&#xff1f; 这里推荐一个平台&#xff1a;wildCard waildCard…

2核4g服务器能支持多少人访问?并发数性能测评

2核4g服务器能支持多少人访问&#xff1f;支持80人同时访问&#xff0c;阿腾云使用阿里云2核4G5M带宽服务器&#xff0c;可以支撑80个左右并发用户。阿腾云以Web网站应用为例&#xff0c;如果视频图片媒体文件存储到对象存储OSS上&#xff0c;网站接入CDN&#xff0c;还可以支持…

String 的使用注意事项

String类型变量不可变 string类型的变量不可变&#xff0c;下面的拼接是怎么回事呢? // 拼接字符串 String str1 "hello"; String str2 "world"; String str3 str1 str2; System.out.println(str3);拼接都会新建 一个常量字符串一个拼接之后的字符串 …

【Unity】分拣机的数字双胞胎集成到Unity3D开发平台中

Unity HMI 一、前言 该项目的重点是通过OPC UA进行客户端-服务器通信的简单演示&#xff0c;该演示在Unity3D中实现&#xff08;服务器- B&R Automation PLC&#xff0c;客户端- Unity3D&#xff09;。该项目展示了数字孪生的分拣机与一些额外的功能。该应用程序使用多线程…

S32 Design Studio PE工具配置ADC

工具配置 我这个K1芯片有两个ADC驱动&#xff0c;也就有两个components&#xff0c;点开之后每个components都有四个选项卡converter转换器、channel通道、compare比较器、average求平均。 配置引脚 配置之前&#xff0c;得先配置好引脚&#xff0c;哪个引脚用来采集ADC。 每…

亚洲股市下一步的关键:中国看财报、日本看汇率、韩国看治理、印度看基建

汇丰认为财报将是驱动中国股市走势的关键因素。目前市场预计2024年中国企业每股收益将增长16%。 日本央行转向、A股业绩复苏、印度基建、韩国市场改革......最近这段时间&#xff0c;亚洲各大市场涌现出了不同的交易主题。 汇丰银行指出&#xff0c;中国受到本土企业盈利能力…

域控操作八:下发打印机策略

、此方法可以直接下发打印机&#xff0c;加域OU后自动连接 1&#xff0c;在域控服务器上安装打印机确保域控可以让打印机使用 并且要开共享入目录 这个共享路径正常情况下应该是在运行里面输入是直接能连接打印机的

算法——链表王

链表刷题详解 203.移除链表元素 力扣题目链接(opens new window) 题意&#xff1a;删除链表中等于给定值 val 的所有节点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 示例 2&#xff1a; 输入&#xff1a;head []…

数据库(mysql)-新手笔记(主外键,视图)

主外键 主键(唯一性,非空性) 主键是数据库表中的一个或多个字段&#xff0c;其值唯一标识表中的每一行/记录。 唯一性: 主键字段中的每个值都必须是唯一的&#xff0c;不能有两个或更多的记录具有相同的主键值 非空性&#xff1a;主键字段不能包含NULL值。 外键(引用完整 …

AutoPSA里给定了弹簧刚度,为什么计算没有引用?

山东一用户问&#xff1a;已经给定了弹簧刚度&#xff0c;为什么计算没引用&#xff1f; 在AutoPSA里包含两种算法仿CAESARII &#xff0c;仿GLIF算法。 在仿CAESARII算法里直接给定弹簧刚度与安载荷载&#xff0c;两个都给了相应值&#xff0c;也就是给定了弹簧号&#xff1b…

处理error: remote origin already exists.及其Gitee文件上传保姆级教程

解决error: remote origin already exists.&#xff1a; 删除远程 Git 仓库 git remote rm origin 再添加远程 Git 仓库 git remote add origin &#xff08;HTTPS&#xff09; 比如这样&#xff1a; 然后再push过去就ok了 好多人可能还是不熟悉怎么将文件上传 Gitee:我…

Python实习生(自动化测试脚本开发) - 面经 - TCL新技术有限公司

JD&#xff1a; 招聘流程&#xff1a; 2024.1.3 Boss直聘 沟通 2024.1.4 约面 2024.1.6 上午面试 面试流程&#xff1a; 上来第一步&#xff0c;直接问Python基础语法&#xff0c;讲一下基础的数据类型 就记得元组和字典 分别具体说一下元组和字典 流程控制语句有哪些&…

应急布控球远程视频监控方案:视频监控平台EasyCVR+4G/5G应急布控球

随着科技的不断发展&#xff0c;应急布控球远程视频监控方案在公共安全、交通管理、城市管理等领域的应用越来越广泛。这种方案通过在现场部署应急布控球&#xff0c;实现对特定区域的实时监控&#xff0c;有助于及时发现问题、快速响应&#xff0c;提高管理效率。 智慧安防视…

SPFA找负环

2024-01-31&#xff08;最短路径&#xff09;-CSDN博客 求负环的常用方法&#xff0c;基于spfa&#xff1a; 1.统计每个点入队的次数&#xff0c;如果有个点入队n次&#xff0c;则说明存在负环 2.统计当前每个点的最短路中包含的边数&#xff0c;如果某个点的最短路的所包含的边…

QT:用opencv的KNN识别图片中的LED数字(一)

前言 一款功能测试的软件demo,使用了QT作为界面,主要使用了opencv的KNN识别,使用gstreamer作为管道,用来打开图片。后期会写一篇打开摄像头实时识别的文章。 (正在写,未完成,稍候) 效果一预览: 效果二预览: 效果三预览: 正在写。。。 设计思路 1. 软件UI设…