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

C++ 中的 string 类:全面解析与应用实践(上)

🤖🌟 欢迎降临张有志的未来科技实验室🤖🌟

专栏:C++             

👨‍💻👩‍💻 先赞后看,已成习惯👨‍💻👩‍💻

👨‍💻👩‍💻 创作不易,多多支持👨‍💻👩‍💻

🚀 启动创新引擎,揭秘C++的密码🚀


 

引言 

  • 编程中字符串至关重要。无论是构建用户界面、处理数据还是网络通信,都离不开字符串操作。
  • C 语言里的 char 数组处理字符串时,需手动管理内存,容易出现缓冲区溢出等错误,像字符串拼接、复制等常见操作,代码编写繁琐且易出错。
  • C++ 的 string 类则是强大的字符串处理工具。它能自动处理内存分配与释放,避免手动管理的风险。还提供大量实用成员函数,如拼接、查找、替换、比较等操作都很便捷,可有效提升开发效率,助力开发者专注核心业务逻辑,在 C++ 编程里处理字符串极为得力。

💡目录

引言 

一、string 类基础

string 类对象的创建及初始化

二、string 类基本操作

(一)字符串访问

(二)字符串长度获取

(三)字符串拼接

(四) 探讨拼接时的内存管理与性能优化( reserve( ) 方法的应用)

(五)空字符串的判断

三、string类对象的比较

1.==、>、<、!= 等运算符在 string 类中的应用

2. compare() 方法的深入讲解,包括返回值含义与多参数用法

区分大小写与不区分大小写比较的实现方式及应用场景

区分大小写比较

不区分大小写比较

string常用成员函数​编辑


一、string 类基础

C++ 标准库(Standard Template Library, STL)是 C++ 的核心组成部分之一,提供了丰富的数据结构和算法。

<string> 是 C++ 标准库中用于处理字符串的头文件。

在 C++ 中,字符串是由字符组成的序列。<string>头文件提供了 std::string 类,它是对 C 风格字符串的封装,提供了更安全、更易用的字符串操作功能。

想要使用string类,需包含头文件stringiostream:

#include<iostream>
#include<string>

string 类对象的创建及初始化

1. 直接赋值初始化

#include<iostream>
#include<string>int main(){std::string str1 = "Hello, World!";std::cout << str1 << std::endl;return 0;
}

2.默认构造函数

#include <iostream>
#include <string>int main() {std::string str2;std::cout << "str2的长度为: " << str2.length() << std::endl;return 0;
}

3.指定长度初始化

#include <iostream>
#include <string>int main() {std::string str4(10, 'a');std::cout << str4 << std::endl;return 0;
}


二、string 类基本操作

(一)字符串访问

1.下标访问

#include <iostream>
#include <string>int main() {std::string str = "Hello";char firstChar = str[0];  // 获取字符串的第一个字符 'H'std::cout << "第一个字符: " << firstChar << std::endl;// 也可以修改单个字符str[0] = 'J';std::cout << "修改后的字符串: " << str << std::endl;return 0;
}

2.迭代器遍历

#include <iostream>
#include <string>int main() {std::string str = "World";std::string::iterator it;for (it = str.begin(); it!= str.end(); ++it) {std::cout << *it;}std::cout << std::endl;return 0;
}

  1. string类提供了 begin()和 end() 函数分别返回指向字符串开头和结尾(不包含最后一个字符)的迭代器
  2. 可以使用常量迭代器 const_iterator 来遍历不可修改的字符串,以增强程序的安全性和规范性。

(二)字符串长度获取

1. length()  size() 方法的使用及区别

string 类中的 length() 和 size()方法在功能上基本相同,都用于获取字符串中字符的数量,并返回 size_t 类型。

#include <iostream>
#include <string>int main() {std::string str = "Test String";std::cout << "字符串长度(length): " << str.length() << std::endl;std::cout << "字符串长度(size): " << str.size() << std::endl;return 0;
}

2. 获取字符串长度并应用于实际逻辑

#include <iostream>
#include <string>int main() {std::string password;std::cout << "请输入密码: ";std::cin >> password;if (password.length() < 8) {std::cout << "密码长度不足 8 位,请重新输入。" << std::endl;// 可以在这里进行重新输入密码等相关逻辑处理} else {std::cout << "密码长度符合要求。" << std::endl;}return 0;
}

(三)字符串拼接

1. 使用 + 运算符拼接字符串

#include <iostream>
#include <string>int main() {std::string firstName = "John";std::string lastName = "Doe";std::string fullName = firstName + " " + lastName;std::cout << "全名: " << fullName << std::endl;return 0;
}

2. append( ) 函数

#include <iostream>
#include <string>int main() {std::string str1 = "Hello";std::string str2 = " World";std::string str3 = "!";// 拼接一个字符串str1.append(str2);// 拼接一个字符串的一部分str1.append(str3, 0, 1);std::cout << str1 << std::endl;return 0;
}

这里先将 str2 拼接到 str1 后面,然后将 str3 的从索引 0 开始长度为 1 的部分(即 '!')拼接到 str1 上。

(四) 探讨拼接时的内存管理与性能优化( reserve( ) 方法的应用)

当进行多次字符串拼接时,如果不加以优化,可能会导致频繁的内存重新分配,降低程序性能

#include <iostream>
#include <string>int main() {std::string result;for (int i = 0; i < 1000; ++i) {std::string temp = std::to_string(i);result += temp;}std::cout << result << std::endl;return 0;
}

每次执行 result += temp 时,string 对象可能会重新分配内存来容纳新拼接的内容。为了避免这种情况,可以使用 reserve() 方法预先分配足够的内存空间

#include <iostream>
#include <string>int main() {std::string result;int estimatedLength = 0;for (int i = 0; i < 1000; ++i) {std::string temp = std::to_string(i);estimatedLength += temp.length();}result.reserve(estimatedLength);for (int i = 0; i < 1000; ++i) {std::string temp = std::to_string(i);result += temp;}std::cout << result << std::endl;return 0;
}

首先预估字符串的长度并提前开辟空间,以此来避免多次开辟空间降低效率

#include <iostream>
#include <string>
#include <ctime>// 未优化的多次字符串拼接函数
void withoutReserve() {std::string result;for (int i = 0; i < 1000; ++i) {std::string temp = std::to_string(i);result += temp;}
}// 使用reserve优化后的多次字符串拼接函数
void withReserve() {std::string result;int estimatedLength = 0;for (int i = 0; i < 1000; ++i) {std::string temp = std::to_string(i);estimatedLength += temp.length();}result.reserve(estimatedLength);for (int i = 0; i < 1000; ++i) {std::string temp = std::to_string(i);result += temp;}
}int main() {clock_t start1, end1, start2, end2;// 测量未优化代码的执行时间start1 = clock();withoutReserve();end1 = clock();// 测量优化后代码的执行时间start2 = clock();withReserve();end2 = clock();double time1 = static_cast<double>(end1 - start1) / CLOCKS_PER_SEC;double time2 = static_cast<double>(end2 - start2) / CLOCKS_PER_SEC;std::cout << "未使用reserve的代码执行时间: " << time1 << " 秒" << std::endl;std::cout << "使用reserve的代码执行时间: " << time2 << " 秒" << std::endl;return 0;
}

使用reserve()函数后,效率明显提高(在数据较大时)

(五)空字符串的判断

1. 使用empty()函数

std::string strToCheck = "";
if (strToCheck.empty()) {std::cout << "这是一个空字符串。" << std::endl;
}

2.比较长度

std::string anotherStrToCheck;
if (anotherStrToCheck.length() == 0) {std::cout << "这个字符串长度为0,是一个空字符串。" << std::endl;
}


三、string类对象的比较

1.==><!= 等运算符在 string 类中的应用

#include <iostream>
#include <string>int main() {std::string str1 = "apple";std::string str2 = "banana";std::string str3 = "apple";if (str1 == str3) {std::cout << "str1 和 str3 相等" << std::endl;}if (str1!= str2) {std::cout << "str1 和 str2 不相等" << std::endl;}return 0;
}

2. compare() 方法的深入讲解,包括返回值含义与多参数用法

compare( ) 的基本用法是将当前字符串与另一个字符串进行比较,返回值为一个整数,其含义如下:

  • 如果当前字符串小于比较的字符串,返回值小于 0
  • 如果当前字符串等于比较的字符串,返回值等于 0
  • 如果当前字符串大于比较的字符串,返回值大于 0
#include <iostream>
#include <string>// 函数用于比较两个完整字符串
void compareFullStrings() {std::string strX = "hello";std::string strY = "world";int result = strX.compare(strY);if (result < 0) {std::cout << "strX 小于 strY" << std::endl;}
}// 函数用于从指定位置和长度比较字符串与子串
void compareSubstring() {std::string longStr = "This is a long string";std::string subStr = "long";// 从索引10开始比较,比较长度为4int posResult = longStr.compare(10, 4, subStr);if (posResult == 0) {std::cout << "从索引10开始的子串与subStr相等" << std::endl;}
}int main() {std::cout << "比较两个完整字符串的结果:" << std::endl;compareFullStrings();std::cout << "比较指定位置子串的结果:" << std::endl;compareSubstring();return 0;
}

区分大小写与不区分大小写比较的实现方式及应用场景

区分大小写比较

如前面所述,使用比较运算符(> == < != )和compare方法都是区分大小写的比较。这种比较方式在很多场景下是适用的,比如密码验证(包括大小写)才能通过验证

#include <iostream>
#include <string>int main() {std::string storedPassword = "Abc123";std::string inputPassword;std::cout << "请输入密码: ";std::cin >> inputPassword;if (inputPassword == storedPassword) {std::cout << "密码正确" << std::endl;} else {std::cout << "密码错误" << std::endl;}return 0;
}

不区分大小写比较

在一些场景中,例如文件名比较或者文本搜索时,可能不需要区分大小写。实现不区分大小写比较可以通过将字符串转换为统一的大小写形式后再进行比较。例如,可以使用 transform 函数结合 tolower 或 toupper 函数来实现。以下是一个不区分大小写比较两个字符串的示例

#include <iostream>
#include <algorithm>
#include <string>bool caseInsensitiveCompare(const std::string& str1, const std::string& str2) {std::string str1Copy = str1;std::string str2Copy = str2;std::transform(str1Copy.begin(), str1Copy.end(), str1Copy.begin(), [](unsigned char c) { return std::tolower(c); });std::transform(str2Copy.begin(), str2Copy.end(), str2Copy.begin(), [](unsigned char c) { return std::tolower(c); });return str1Copy == str2Copy;
}int main() {std::string file1 = "TEST.TXT";std::string file2 = "test.txt";if (caseInsensitiveCompare(file1, file2)) {std::cout << "文件名不区分大小写比较相等" << std::endl;} else {std::cout << "文件名不区分大小写比较不相等" << std::endl;}return 0;
}


string常用成员函数

相关文章:

C++ 中的 string 类:全面解析与应用实践(上)

&#x1f916;&#x1f31f; 欢迎降临张有志的未来科技实验室&#x1f916;&#x1f31f; 专栏&#xff1a;C &#x1f468;‍&#x1f4bb;&#x1f469;‍&#x1f4bb; 先赞后看&#xff0c;已成习惯&#x1f468;‍&#x1f4bb;&#x1f469;‍&#x1f4bb;…...

量化交易系统开发-实时行情自动化交易-8.7.文华平台

19年创业做过一年的量化交易但没有成功&#xff0c;作为交易系统的开发人员积累了一些经验&#xff0c;最近想重新研究交易系统&#xff0c;一边整理一边写出来一些思考供大家参考&#xff0c;也希望跟做量化的朋友有更多的交流和合作。 接下来会对于文华平台介绍。 文华财经…...

美畅物联丨如何通过 FFmpeg 解码视频

FFmpeg是一款功能强大、在多媒体处理领域广泛应用的开源工具。它可以处理多种音频和视频格式&#xff0c;包含编码、解码、转码、流媒体处理等众多功能。前两天&#xff0c;我们在《美畅物联丨如何通过FFmpeg排查视频问题》一文中介绍了借助FFmpeg程序来辅助判断视频播放异常的…...

机器学习任务功略

loss如果大&#xff0c;训练资料没有学好&#xff0c;此时有两个可能&#xff1a; 1.model bias太过简单&#xff08;找不到loss低的function&#xff09;。 解决办法&#xff1a;增加输入的feacture&#xff0c;设一个更大的model&#xff0c;也可以用deep learning增加弹性…...

Web Worker 和 WebSocket的区别

Web Worker&#xff08;消息传递机制&#xff09; 定义&#xff1a;是为了在浏览器中提供多线程支持&#xff0c;允许 JavaScript 在后台线程运行&#xff0c;而不阻塞主线程。它非常适合执行耗时的计算任务或处理大量数据&#xff0c;避免主线程&#xff08;通常是 UI 线程&a…...

JMeter实时性能压测可视化系统整合

一、相关工具简介: JMeter、Grafana 和 InfluxDB 结合实时地收集、分析和展示性能测试数据,进行更好地理解系统的性能表现,及时发现潜在问题并进行优化。 1,JMeter 实时生成性能数据,并将其发送到 InfluxDB 进行存储。2,InfluxDB 存储的数据。3,通过Grafana的仪表板,用…...

无限加载和懒加载及路由滚动及路由滚动不生效

这里写目录标题 列表无限加载懒加载定制路由滚动使用scrollBehavior不起效不管用的原因使用scrollTo来实现路由滚动elMain && elMain.scrollTo(...) 的作用是&#xff1a; 无限加载和懒加载的区别 列表无限加载 无限加载功能在现代网页和移动应用中广泛应用&#xff0…...

CSS底层基础:小白速来

1. CSS简介 CSS (Cascading Style Sheets) 是一种用来描述HTML或XML文档样式的语言。它使得开发者能够控制网页的布局和外观&#xff0c;包括字体、颜色、间距等。CSS通过选择器来指定要应用样式的元素&#xff0c;并定义这些元素的具体样式属性。 基本结构示例&#xff1a; …...

【MySQL 进阶之路】索引概述

第06章_索引 1.什么是索引 索引是存储引擎用于快速找到数据记录的一种数据结构&#xff0c;就好比一本教科书的目录部分&#xff0c;通过目录中找到对应文章的页码&#xff0c;便可快速定位到需要的文章。MySQL中也是一样的道理&#xff0c;进行数据查找时&#xff0c;首先查…...

【C++boost::asio网络编程】有关异步读写api的笔记

异步读写api 异步写操作async_write_someasync_send 异步读操作async_read_someasync_receive 定义一个Session类&#xff0c;主要是为了服务端专门为客户端服务创建的管理类 class Session { public:Session(std::shared_ptr<asio::ip::tcp::socket> socket);void Conn…...

Elasticsearch 的存储与查询

Elasticsearch 的存储与查询 在搜索系统领域&#xff0c;数据的存储与查询是两个最基础且至关重要的环节。Elasticsearch(ES) 在这两方面进行了深度优化&#xff0c;使其在关系型数据库或非关系型数据库中脱颖而出&#xff0c;成为搜索系统的首选。 映射 (Mapping) 映射 (Ma…...

008静态路由-特定主机路由

按照如上配置&#xff0c;用192.168.0.1 电脑ping 192.168.1.1 发现能够ping通 用192.168.0.1 电脑ping 192.168.2.1 发现不能ping通 这是因为192.168.0.1 和 192.168.1.1 使用的是同一个路由器R1。 192.168.0.1 和 192.168.2.1 通信需要先经过R1&#xff0c;再经过R2 &#xf…...

SystemUI 下拉框 Build 版本信息去掉

需求及场景 去掉SystemUI 下拉框 Build 版本信息 如下图所示&#xff1a;去掉 12 &#xff08;SP1A.201812.016) 了解 去掉之前我们先了解它是个什么东西:其实就是一个Build RTM 信息显示 Android_12_build_SP1A.210812.016 修改文件 /frameworks/base/packages/Syste…...

【JS】栈内存、堆内存、事件机制区别、深拷贝、浅拷贝

js中&#xff0c;内存主要分为两种类型&#xff1a;栈内存&#xff08;stack&#xff09;、堆内存&#xff08;heap&#xff09;&#xff0c;两种内存区域在存储和管理数据时有各自的特点和用途。 栈内存 访问顺序 栈是先进后出、后进先出的数据结构&#xff0c;栈内存是内存用…...

如何确保Java爬虫获得1688商品详情数据的准确性

在数字化商业时代&#xff0c;数据的价值日益凸显&#xff0c;尤其是对于电商平台而言。1688作为中国领先的B2B电子商务平台&#xff0c;提供了海量的商品数据接口&#xff0c;这些数据对于市场分析、库存管理、价格策略制定等商业活动至关重要。本文将详细介绍如何使用Java编写…...

【蓝牙通讯】iOS蓝牙开发基础介绍

1. iOS 蓝牙开发基础 在 iOS 中&#xff0c;蓝牙的操作主要是通过 Core Bluetooth 框架来实现。理解 Core Bluetooth 的基本组件和工作原理是学习 iOS 蓝牙开发的第一步。 核心知识点&#xff1a; Core Bluetooth 框架&#xff1a;这是 iOS 系统提供的专门用于蓝牙低功耗&am…...

Vue 90 ,Element 13 ,Vue + Element UI 中 el-switch 使用小细节解析,避免入坑(获取后端的数据类型自动转变)

目录 前言 在开发过程中&#xff0c;我们经常遇到一些看似简单的问题&#xff0c;但有时正是这些细节问题让我们头疼不已。今天&#xff0c;我就来和大家分享一个我在开发过程中遇到的 el-switch 使用的小坑&#xff0c;希望大家在使用时能够避免。 一. 问题背景 二. 问题分…...

echarts的双X轴,父级居中的相关配置

前言&#xff1a;折腾了一个星期&#xff0c;在最后一天中午&#xff0c;都快要放弃了&#xff0c;后来坚持下来&#xff0c;才有下面结果。 这个效果就相当是复合表头&#xff0c;第一行是子级&#xff0c;第二行是父级。 子级是奇数个时&#xff0c;父级label居中很简单&…...

RuoYi-Vue部署到Linux服务器(Jar+Nginx)

一、本地环境准备 源码下载、本地Jdk及Node.js环境安装,参考以下文章。 附:RuoYi-Vue下载与运行 二、服务器环境准备 1.安装Jdk 附:JDK8下载安装与配置环境变量(linux) 2.安装MySQL 附:MySQL8免安装版下载安装与配置(linux) 3.安装Redis 附:Redis下载安装与配置(…...

Linux firewalld常用命令

启动防火墙 systemctl start firewalld 停止防火墙 systemctl stop firewalld 防火墙开机自启动 systemctl enable firewalld 禁止防火墙开机自启动 systemctl disable firewalld 检查防火墙的状态 systemctl status firewalld 重新加载防火墙的配置 firewall-cmd -…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...