C++string类介绍

news/2024/9/16 22:24:19/

目录

一、介绍

二、string类对象的构造 

string类有如下构造方法: 

 类对象的容量操作

类对象访问及遍历 

string对象的修改操作:

std::string::insert

std::string::erase

 std::string::c_str

std::string::find

std::string::substr 


一、介绍

1. 字符串是表示字符序列的类
2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型。
4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数。
5. 这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

注意:使用string类时,必须包含#include头文件以及using namespace std; 

二、string类对象的构造 

string类有如下构造方法: 

 代码案例:

void test()
{string s1; // 构造空的string类对象s1string s2("hello string"); // 用C格式字符串构造string类对象s2string s3(s2); // 拷贝构造s3cout << s2 << " " << s3 << endl;char s4[] = "hello world!!!";string s5(s4);//拷贝构造s5,从char*s4拷贝过来cout << s5 << endl;string s6(s4, 3);//拷贝构造,从s4的前3个位置字符cout << s6 << endl;string s7(4, 'c');//构造s7,由4个字符‘c’构成的字符串cout << s7 << endl;
}

 类对象的容量操作

函数名称功能说明
size返回字符串有效长度
length返回字符串有效长度
capacity返回空间总大小
empty

检测字符串释放为空串,是 返回true,否 返回false

clear清空有效字符
reserve为字符串预留空间
resize将有效字符的个数改成n个,多出的空间用字符C填充

注意:

 1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
2. clear()只是将string中有效字符清空,不改变底层空间大小。
3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

代码案例: 

void Teststring1()
{// 注意:string类对象支持直接用cin和cout进行输入和输出string s("hello, string!!!");cout << s.size() << endl;cout << s.length() << endl;cout << s.capacity() << endl;cout << s << endl;// 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小cout << "clear:" << endl;s.clear();cout << s.size() << endl;cout << s.capacity() << endl;// 将s中有效字符个数增加到10个,多出位置用'a'进行填充// “aaaaaaaaaa”cout << "resize:" << endl;s.resize(10, 'a');cout << s.size() << endl;cout << s.capacity() << endl;// 将s中有效字符个数增加到15个,多出位置用缺省值'\0'进行填充// "aaaaaaaaaa\0\0\0\0\0"// 注意此时s中有效字符个数已经增加到15个s.resize(15);cout << s.size() << endl;cout << s.capacity() << endl;cout << s << endl;// 将s中有效字符个数缩小到5个s.resize(5);cout << s.size() << endl;cout << s.capacity() << endl;cout << s << endl;
}

 对于不同的编译器,string初始开辟的空间有所不同,下面是VS2019编译器下的运行结果。

初始开辟的空间大小及每次扩容的大小

void TestPushBackReserve()
{string s;s.reserve(100);size_t sz = s.capacity();cout << "making s grow:\n";for (int i = 0; i < 1000; ++i){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed: " << sz << '\n';}}
}

类对象访问及遍历 

函数名称功能说明
operator[pos]返回pos位置的字符
begin+endbegin获取一个字符迭代器+end获取最后一个位置迭代器
rbegin+rend

(逆向)rbegin获取最后一个字符迭代器+rend获取首个位置迭代器

范围forC++11支持更简洁的范围for的鑫遍历方式

代码案例:

void test()
{string s("hello Bit");//for遍历operator[]for (int i = 0; i < s.size(); i++){cout << s[i] << " ";}cout << "    operator[]:" << endl;//迭代器遍历 begin+endstring::iterator it = s.begin();//创建迭代器while (it != s.end()){cout << *it <<" ";++it;}cout << "   迭代器begin+end" << endl;//迭代器 rbegin+rendstring::reverse_iterator rit = s.rbegin();//创建迭代器while (rit != s.rend()){cout << *rit << " ";++rit;}cout<< "    迭代器rbegin+rend" << endl;//范围forfor (auto ch : s){cout << ch << " ";}cout << "    范围for" << endl;
}

  

string对象的修改操作:

函数名称功能说明
push_back在字符串后面尾插字符
append在字符串后面追加一个字符
operator+=在字符串后面追加字符、字符串

代码案例:

void push()
{string s("hello");//构造并初始化对象cout << s << endl;s.push_back(' ');//尾插一个字符cout << s << endl;s.append("str");//追加字符串cout << s << endl;s += "ing";//追加字符串cout << s << endl;
}

std::string::insert

函数名称功能说明
 string& insert (size_t pos, const string& str);

在原串下标为pos的字符前插入字符串str

string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);

str从下标为subpos开始数的sublen个字符插在原串下标为pos的字符前

string& insert (size_t pos, const char* s);
在原串pos位置前插入字符串*s
string& insert (size_t pos, const char* s, size_t n);
在原串pos位置前插入字符串s前n个字符
string& insert (size_t pos, size_t n, char c);

在原串下标为pos的字符前插入n个字符c

注意:pos是指下标,从0开始 ,都是在之前插入

代码案例:

void test()
{string s1("hello string!!!");cout << s1 << endl;string s2(s1);string s3("it");s2.insert(6, s3);//在小标为6的位置前插入s3cout << s2 << endl;string s4(s1);s4.insert(6, s3, 1, 1);//在下标为6的位置前插入s3的下标为1数的一个字符cout << s4 <<endl;string s5("hello ");s5.insert(5, "world");//在下标为5的位置插入字符串“world”cout << s5 << endl;string s6("hello");s6.insert(4, "ABCD", 2);//在下标为4的位置插入字符串“ABC”的前2个字符cout << s6 << endl;string s7("hello");s7.insert(2, 3, 'A');//在下标为2的位置前插入3个字符'A'cout << s7 << endl;
}

std::string::erase

string& erase(size_t pos,size_t len)

删除pos位置起len个长度字符

len过长就有多少删多少

pos不是指的下标

代码案例: 

void test()
{string s1{ "hello string" };s1.erase(6, 5);//删除第六个位置起的五个字符cout << s1 << endl;
}

 std::string::c_str

Get C string equivalent (public member function)返回C字符串

代码案例: 

如下,以C形式读取文件,如果使用string去运行会报错,只能使用c_str转换为C使用才能编译成功:

void test()
{string filename("test.cpp");  //通过string表示出文件名文件名FILE* fout = fopen(filename.c_str(), "r");//读取该文件assert(fout);//断言char ch = fgetc(fout);//打印文件内容while (ch != EOF){cout << ch;ch = fgetc(fout);//打印文件内容}
}
//这里的test.cpp文件是我的编译下的.cpp源文件

 打印结果案例:

void test()
{string filename("test.cpp");cout << filename << endl;cout << filename.c_str() << endl;filename += '\0';filename += "string.cpp";cout << filename << endl;//string对象以size为准cout << filename.c_str() << endl;//常量字符串对象以\0为准
}

为什么打印结果不一样呢?

 string对象的结束是以size大小(总长度)为准

常量字符串(c_str)结束是以‘\0’为准(遇到就截止)

std::string::find

函数名称功能介绍
size_t find (const string& str, size_t pos = 0) 

在原串中从pos位置开始,找str在原串中的下标位置,找到返回下标,没找到返回-1

pos是下标

pos可以不写,就从0下标位置开始往后找

size_t find (const char* s, size_t pos = 0)
同上
size_t find (const char* s, size_t pos, size_t n)
在原串中从pos位置,找s中的n个字符首次出现的下标位置
size_t find (char c, size_t pos = 0)

在原串中从pos位置往后找字符c首次出现的下标

pos可省略,从下标为0开始找

代码案例:

void test()
{string s1("hollo world!!!");string s2{ "world" };int pos = s1.find(s2,1);//在原串中从下标为1的位置找s2,返回该位置的下标cout << pos << endl;char s3[] = "!!!";pos = s1.find(s3, 2);//在原串中从小标为2的位置找字符串s3的位置,返回下标cout << pos << endl;pos = s1.find("world", 1, 2);//在原串中从下标为1的位置,找字符串“world”中的n个字符出现的位置cout << pos << endl;pos = s1.find('o', 2);//在原串中从pos位置找字符‘o’首次出现的位置cout << pos << endl;
}

 

std::string::rfind        

使用形式跟find 一样,参数都一样的,唯一的区别是find是从前往后找,rfind是从后往前找

 

std::string::substr 

string substr (size_t pos = 0, size_t len = npos) const;

从pos位置开始截取len个字符长度,再返回

len可以没有,就从pos开始一直往后截取

注意:这里是返回截取后的字符串,而不是在原串上更改 

代码案例:

void test()
{string s1("hello world!!!");string s2 = s1.substr(6);//从下标为6的位置开始截取,一直到截完为止cout << "s2:" << s2 << endl;string s3 = s1.substr(6, 8);//从下标为6的位置开始截取8个字符cout << "s3:" << s3 << endl;
}

 如果发现有什么问题或建议欢迎提出!!!

谢谢阅读!!!


http://www.ppmy.cn/news/8729.html

相关文章

将Android进行到底之内容提供者(ContentProvider)

文章目录前言一、ContentProvider是什么&#xff1f;二、使用示例1.为应用创建内容提供者2.使用内容提供者2.1 内容URI2.2 Uri参数解析2.2 使用内容URI操作数据3.ContentProvider妙用4 内容URI对应的MIME类型5.ContentProvider重点注意6 演示demo源码总结前言 随着现在的应用越…

[ASIS 2022 last CTF] 2022最后一赛

这个比赛太难了&#xff0c;就作了4个题 Crypto Bedouin 题目非常短&#xff0c;就是先生成一个小素数&#xff0c;然后堆到一起l次再补个1&#xff0c;比如235就变成2352352351这样&#xff0c;一开始以为是2进制&#xff0c;一直没作出来&#xff0c;方式也没错。后来发现原…

Unsupported conversion from LONG to java.sql.Timestamp

使用mybatisplus查询实体时报错Unsupported conversion from LONG to java.sql.Timestamp 先说结论&#xff1a; mybatis建议实体类上带上无参构造,当然java类虽然默认提供无参构造&#xff0c;但是现在都会用Data注解简化开发&#xff0c;里面会有 有参构造 所以默认的无参构造…

python自动化编程--正则表达式

目录 一.创建正则表达式 1.re模块 2.匹配Regex对象 二.正则表达式匹配更多模式 1.用括号分组 2.用管道匹配多个分组 3.用问号表示可选 4.用星号匹配零次或多次 5.用加号表示匹配一次或多次 6.用花括号匹配特定次数 三.贪心和非贪心匹配 四.字符分类 五.自定义字符…

QML教程(七) JavaScript

目录 一、对属性值使用 JavaScript 表达式 二、在 QML 中添加 JavaScript 函数 三、使用 JavaScript 文件 四、属性绑定中的 JavaScript 五、信号处理程序中的 JavaScript 六、将信号连接到 JavaScript 函数 七、启动执行 JavaScript QML 提供的 JavaScript 主机环境可以…

系统管理员喜欢 systemd 的 5 个理由

导读systemd 的速度和易用性使其成为管理现代 Linux 系统的流行方式。 系统管理员知道&#xff0c;在一台运行着的现代计算机上会发生很多事情&#xff1a;应用程序在后台运行、预定事件等待在特定时间被触发、事件写入日志文件、发送状态报告。在以前&#xff0c;不同的进程可…

2022年终总结与展望

2022年终总结 自2019年3月13日入驻CSDN&#xff0c;已经三年零九个月了。截至2022年12月31日&#xff0c;CSDN博客已发原创博文112篇&#xff0c;粉丝3616个&#xff0c;访问量超过157万次。 2019年12月31日数据情况&#xff1a; 2020年12月31日数据情况&#xff1a; 2021年1…

JAVA练习8

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、题目1- 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 二、题目2- 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示&#xff1a;这里可以…

数据结构(一)

单链表 // head存储链表头&#xff0c;e[]存储节点的值&#xff0c;ne[]存储节点的next指针&#xff0c;idx表示当前用到了哪个节点 int head, e[N], ne[N], idx; // 初始化 void init() { head -1; idx 0; } // 在链表头插入一个数a void insert(int a) { e[idx] a, ne[i…

mysql事务一致性,原子性,持久性实现以及锁区别

Mysql事务一致性&#xff0c;原子性是如何实现的? 首先是通过锁和mvcc实现了执行过程中的一致性和原子性 其次是在灾备方面通过Redo log实观&#xff0c;Redo log会把事务在执行过程中对数据库所做的所有修改都记录下来&#xff0c;在之后系统崩溃重启后把事务所做的任何修改都…

Faster RCNN网络源码解读(Ⅸ) --- ROIAlign、TwoMLPHead、FastRCNNPredictor部分解析

目录 一、回顾以及本篇博客内容概述 二、代码解析 2.1 FasterRCNNBase类 2.1.1 forward正向传播 2.2 FasterRCNN类 2.2.1 roi_heads定义 2.3 TwoMLPHead类&#xff08;faster_rcnn_framework.py&#xff09; 2.4 FastRCNNPredictor类 2.5 RoIHeads类&#xff08;roi_…

四【Servlet基础】文件配置及环境搭建(重要)

文章目录4.1 Servlet概念4.2 Servlet作用4.3 Servlet开发步骤4.3.1 搭建开发环境4.3.2 创建项目4.3.3 部署Servlet4.3.4 配置Servlet4.3.5 测试运行4.1 Servlet概念 &#xff08;1&#xff09;Servlet&#xff1a;Server Applet的简称&#xff0c;是运行在Web服务器端的Java程…

2.0、Linux-基础了解

2.0、开机关机和基本目录介绍 开机登录&#xff1a; 开会机会启动许多程序&#xff1b;他们在Windows叫做 "服务" &#xff0c;在 Linux 中叫做 "守护进程"&#xff08;daemon&#xff09;&#xff1b; 开机成功后&#xff0c;他会显示一个文本登录…

【网络】网络发展,网络协议,网络传输流程,地址管理

目录 1.计算机网络背景 1.1网络发展 局域网和广域网 1.2 协议 2.网络协议初识 2.1协议分层 2.2OSI七层模型 2.3 TCP/IP 五层&#xff08;或四层&#xff09;模型 网络和操作系统之间的关系 2.4重谈协议 -- 计算机的视角&#xff0c;如何看待协议&#xff1f; 2.5 网…

【MySQL】MySQL存储过程与存储函数实战(MySQL专栏启动)

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码&#xff0c;就职于大型金融公司后端高级工程师&#xff0c;擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…

第三十六讲:无线AP胖AP模式配置与管理

胖AP(Fat AP)配置一个开放式WLAN非常方便&#xff0c;需要完成的操作包括有线和无线两部分的配置。有线部分即ethernet接口的配置&#xff0c;保证AP能够接入Internet,无线部分的配置包括关联WLAN与VLAN&#xff0c;广播SSID,启用VAP&#xff0c;若无其他DHCP服务器的话&#x…

高并发系统设计 -- 服务限流算法

常见的限流算法 漏桶算法 漏桶法的关键点在于漏桶始终按照固定的速率运行&#xff0c;但是它并不能很好的处理有大量突发请求的场景&#xff0c;毕竟在某些场景下我们可能需要提高系统的处理效率&#xff0c;而不是一味的按照固定速率处理请求。 关于漏桶的实现&#xff0c;u…

计算机网络体系结构

目录常见的计算机网络体系结构计算机网络体系结构分层的必要性计算机网络体系结构分层思想举例计算机网络体系结构中的专用术语常见的计算机网络体系结构 TCP/IP体系结构相当于将OSI体系结构的物理层和数据链路层合并为网络接口层。并去掉了会话层和表示层。 由于TCP/IP在网络…

应用上K8S:Gradle打包

需求 对于spring boot项目我们一般使用Maven或Gradle进行编译打包&#xff0c;也可以借助docker plugin进行镜像打包并push到远程仓库。因此在经过《Docker随时随地玩转变量》一文&#xff0c;我们已经确定了Dockerfile&#xff0c;那么应用上K8S第二步&#xff1a;gradle打包…

D2. RGB Substring (hard version)(尺取)

Problem - 1196D2 - Codeforces 通用领域 医学 计算机 金融经济 你有一个包含n个字符的字符串s&#xff0c;每个字符是R&#xff0c; G或B。 你还得到一个整数k。你的任务是改变初始字符串s中的最小字符数&#xff0c;这样在改变之后&#xff0c;将会有一个长度为k的字符串…