第9课-C++String功能的探索

1:C 语言中的字符串 vs C++ string 类

1.1 C 语言中的字符串

在 C 语言中,字符串本质上是以 \0 结尾的字符数组。C 标准库为此提供了 str 系列函数,如 strlen()、strcpy() 和 strcat() 等。虽然这些函数可以操作字符串,但它们的操作十分繁琐且容易出错,尤其是在内存管理方面。

例如,在 C 语言中进行字符串拼接的代码如下:

#include <stdio.h>
#include <string.h>

int main() {
    char str1[50] = "Hello";
    char str2[50] = " World";

    // 字符串连接
    strcat(str1, str2);

    printf("%s\n", str1);  // 输出:Hello World

    return 0;
}


问题:C 语言中的字符串操作容易出现内存溢出,因为需要手动管理字符数组的长度。

1.2 C++ string 类的优势

C++ 中的 string 类使得字符串操作更加安全和简便。它封装了复杂的内存管理,并提供了类似数组的接口,开发者不再需要手动管理字符串的长度和内存。例如,使用 string 进行字符串拼接:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str1 = "Hello";
    string str2 = " World";

    // 使用 += 操作符进行拼接
    str1 += str2;

    cout << str1 << endl;  // 输出:Hello World

    return 0;
}

2:string 类的构造与基础操作

2.1 string 类的构造方法

string 类支持多种构造方式,以下是常见的构造函数:

函数名    功能描述
string()    默认构造一个空字符串
string(const char* s)    使用 C 字符串 s 构造 string 对象
string(size_t n, char c)    构造一个包含 n 个字符 c 的字符串
string(const string& s)    使用已有的 string 对象进行拷贝构造

2.1.1 示例代码:构造字符串

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s1;                 // 空字符串
    string s2("Hello C++");     // 通过C字符串初始化
    string s3(s2);              // 拷贝构造
    string s4(5, 'A');          // 5个'A'字符的字符串

    cout << "s1: " << s1 << endl;
    cout << "s2: " << s2 << endl;
    cout << "s3: " << s3 << endl;
    cout << "s4: " << s4 << endl;

    return 0;
}

输出示例:

s1: 
s2: Hello C++
s3: Hello C++
s4: AAAAA

2.2 string 对象的常见操作

函数名    功能描述
size()    返回字符串的长度
length()    返回字符串的长度,与 size() 等价
capacity()    返回当前分配的存储空间大小
empty()    判断字符串是否为空,若为空返回 true
clear()    清空字符串内容
reserve()    为字符串预留存储空间,不改变有效字符的个数
resize()    改变字符串的长度,若增大则用默认字符填充

2.2.1:字符串容量操作

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

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s = "Hello";

    cout << "Size: " << s.size() << endl;     // 返回字符串长度
    cout << "Capacity: " << s.capacity() << endl;  // 返回容量
    s.resize(10, 'X');                        // 将长度改为10,多出部分用'X'填充
    cout << "Resized: " << s << endl;
    s.clear();                                // 清空字符串
    cout << "Is empty: " << s.empty() << endl;  // 检查是否为空

    return 0;
}

输出示例:

Size: 5
Capacity: 15
Resized: HelloXXXXX
Is empty: 1

2.3 字符串的遍历与访问

可以通过以下几种方式访问字符串中的字符:

方法    功能描述
operator[]    返回或设置指定位置的字符
at()    返回指定位置的字符并进行边界检查
begin()/end()    返回字符串的首尾迭代器,用于遍历字符串
rbegin()/rend()    返回反向迭代器,支持从后向前遍历字符串

push_back()    在字符串末尾追加一个字符
append()    在字符串末尾追加另一个字符串或子字符串

注意:

在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

2.3.1 遍历与访问字符

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s = "Hello C++";

    // 使用下标访问
    cout << "First character: " << s[0] << endl;

    // 使用迭代器遍历
    for (auto it = s.begin(); it != s.end(); ++it) {
        cout << *it << ' ';
    }
    cout << endl;

    return 0;
}

输出示例

First character: H
H e l l o   C + +

3:字符串的高级操作

3.1 字符串的查找操作

string 类提供了多种查找子字符串或字符的方法。常见的查找方法如下:

函数名    功能说明
find()    在字符串中查找子字符串或字符,返回其首次出现的位置,找不到则返回 string::npos
rfind()    反向查找字符串,返回最后一次出现子串或字符的位置

find_first_of()    查找指定字符集中的任意一个字符,返回第一次出现的索引
find_last_of()    查找指定字符集中的任意一个字符,返回最后一次出现的索引
string::npos 是 std::string 类的一个常量静态成员变量,它是用来表示查找操作失败时的返回值。

它通常等于无符号整数类型的最大值(size_t(-1)),具体值是实现定义的,但它在所有实现中都用于表示“未找到”的状态。
 

#include <iostream>
#include <string>
using namespace std;

int main() {
    cout << "Value of string::npos: " << string::npos << endl;
    return 0;
}

输出结果:

Value of string::npos: 18446744073709551615  // 这是 size_t 的最大值 (通常等于 -1)

3.1.1 查找子字符串

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s = "Hello World";

    // 查找 "World" 在字符串中的位置
    size_t pos = s.find("World");
    if (pos != string::npos) {
        cout << "'World' found at position: " << pos << endl;
    } else {
        cout << "'World' not found" << endl;
    }

    // 反向查找 'o'
    size_t rpos = s.rfind('o');
    cout << "'o' last found at position: " << rpos << endl;

    return 0;
}

输出示例:

'World' found at position: 6
'o' last found at position: 7

3.1.2 示例代码:查找任意字符

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s = "Hello, World!";
    string charset = "aeiou";  // 查找元音字母

    // 使用 find_first_of 查找字符集中任意字符第一次出现的位置
    size_t first_pos = s.find_first_of(charset);
    if (first_pos != string::npos) {
        cout << "First vowel in the string found at position: " << first_pos << endl;
    } else {
        cout << "No vowel found in the string." << endl;
    }

    // 使用 find_last_of 查找字符集中任意字符最后一次出现的位置
    size_t last_pos = s.find_last_of(charset);
    if (last_pos != string::npos) {
        cout << "Last vowel in the string found at position: " << last_pos << endl;
    } else {
        cout << "No vowel found in the string." << endl;
    }

    return 0;
}

输出示例:

First vowel in the string found at position: 1
Last vowel in the string found at position: 8

3.3 字符串的比较操作

在 C++ 中,string 类支持字符串的比较操作,既可以使用运算符 ==、!=、<、> 等,也可以通过 compare() 方法进行更细粒度的比较。

方法    功能说明
operator==    判断两个字符串是否相等
operator!=    判断两个字符串是否不相等
operator<    判断当前字符串是否小于另一个字符串
operator>    判断当前字符串是否大于另一个字符串
compare()    进行详细的字符串比较,返回 0 表示相等,负值表示小于,正值表示大于

3.2.1 :字符串比较

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str1 = "Apple";
    string str2 = "Banana";

    if (str1 == str2) {
        cout << "Strings are equal" << endl;
    } else {
        cout << "Strings are not equal" << endl;
    }

    // 使用 compare() 方法比较
    int result = str1.compare(str2);
    if (result == 0) {
        cout << "Strings are equal" << endl;
    } else if (result < 0) {
        cout << "str1 is less than str2" << endl;
    } else {
        cout << "str1 is greater than str2" << endl;
    }

    return 0;
}

输出示例:

Strings are not equal
str1 is less than str2

3.3字符串的替换操作

在 C++ 中,string 类允许我们通过 replace() 方法替换字符串中的部分内容。

函数名    功能说明
replace()    替换从指定位置开始的若干字符为新字符串

3.3.1 替换字符串中的部分内容

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "Hello World";

    // 替换 "World" 为 "C++"
    str.replace(6, 5, "C++");

    cout << str << endl;  // 输出:Hello C++

    return 0;
}

输出示例:

Hello C++


3.4 字符串的截取操作

string 类提供了 substr() 方法来提取字符串中的子字符串。该方法非常有用,尤其是在处理文件路径或URL时。

函数名    功能说明
substr()    从指定位置开始,截取若干字符并返回子字符串

3.4.1提取子字符串

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "Hello World";

    // 从位置 6 开始截取 5 个字符
    string sub = str.substr(6, 5);

    cout << "Substring: " << sub << endl;

    return 0;
}

输出示例:

Substring: World

3.5字符串的插入与删除操作

在 C++ 中,string 类支持通过 insert() 在字符串的指定位置插入子字符串,或通过 erase() 从指定位置删除字符。

这两个方法因为时间复杂度挺高的,所以还是避免常用

函数名    功能说明
insert()    在字符串的指定位置插入字符或子字符串
erase()    删除字符串中指定位置的若干字符

3.5.1 插入与删除操作

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "Hello World";

    // 在索引 5 处插入一个逗号
    str.insert(5, ",");
    cout << "After insert: " << str << endl;

    // 删除索引 5 开始的 1 个字符
    str.erase(5, 1);
    cout << "After erase: " << str << endl;

    return 0;
}

输出示例:

After insert: Hello, World
After erase: Hello World

3.6 字符串与数值的转换

C++ 提供了 to_string() 和 stoi() 等函数,帮助我们在字符串和数值之间进行转换。这在处理用户输入、文件解析等场景中非常常用。

函数名    功能说明
to_string()    将数值转换为字符串
stoi()    将字符串转换为整数
stof()    将字符串转换为浮点数

3.6.1 数字与字符串的相互转换

#include <iostream>
#include <string>
using namespace std;

int main() {
    int num = 42;
    string str = to_string(num);  // 数字转字符串
    cout << "String: " << str << endl;

    string strNum = "123";
    int parsedNum = stoi(strNum);  // 字符串转整数
    cout << "Parsed Integer: " << parsedNum << endl;

    return 0;
}

输出示例:

String: 42
Parsed Integer: 123

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

简易CPU设计入门:取指令(三),ip_buf与rd_en的非阻塞赋值

在开篇&#xff0c;还是请大家首先准备好本项目所用的源代码。如果已经下载了&#xff0c;那就不用重复下载了。如果还没有下载&#xff0c;那么&#xff0c;请大家点击下方链接&#xff0c;来了解下载本项目的CPU源代码的方法。 下载本项目代码 准备好了项目源代码以后&…

【重学 MySQL】五十一、更新和删除数据

【重学 MySQL】五十一、更新和删除数据 更新数据删除数据注意事项 在MySQL中&#xff0c;更新和删除数据是数据库管理的基本操作。 更新数据 为了更新&#xff08;修改&#xff09;表中的数据&#xff0c;可使用UPDATE语句。UPDATE语句的基本语法如下&#xff1a; UPDATE ta…

【ADC】噪声(1)噪声分类

概述 本文学习于TI 高精度实验室课程&#xff0c;总结 ADC 的噪声分类&#xff0c;并简要介绍量化噪声和热噪声。 文章目录 概述一、ADC 中的噪声类型二、量化噪声三、热噪声四、量化噪声与热噪声对比 一、ADC 中的噪声类型 ADC 固有噪声由两部分组成&#xff1a;第一部分是量…

【重学 MySQL】四十六、创建表的方式

【重学 MySQL】四十六、创建表的方式 使用CREATE TABLE语句创建表使用CREATE TABLE LIKE语句创建表使用CREATE TABLE AS SELECT语句创建表使用CREATE TABLE SELECT语句创建表并从另一个表中选取数据&#xff08;与CREATE TABLE AS SELECT类似&#xff09;使用CREATE TEMPORARY …

【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收

文章目录 1. 标记-清除2. 复制算法4. 标记-整理4. 分代回收 把标记为垃圾的对象的内存空间进行释放。主要有三种释放方式 1. 标记-清除 把标记为垃圾的对象&#xff0c;直接释放掉&#xff08;最朴素的做法&#xff09; 此时就是把标记为垃圾的对象所对应的内存空间直接释放。…

本地化测试对游戏漏洞修复的影响

本地化测试在游戏开发的质量保证过程中起着至关重要的作用&#xff0c;尤其是在修复bug方面。当游戏为全球市场做准备时&#xff0c;它们通常会被翻译和改编成各种语言和文化背景。这种本地化带来了新的挑战&#xff0c;例如潜在的语言错误、文化误解&#xff0c;甚至是不同地区…

k8s中,ingress的实现原理,及其架构。

图片来源&#xff1a;自己画的 图片来源&#xff1a;k8s官网 首先&#xff0c;什么是ingress? 是服务还是控制器&#xff1f; 都不精确 ingress是一个api资源 service和deployment也是api资源。 这几个相互协作&#xff0c;组建成一个对外提供服务的架构。 ingress提供的…

MDM监管锁系统上锁流程

上锁与解锁 上锁设备 完整的上锁流程可参考: https://b23.tv/UvM35sU 上锁需要已经注册了一个普通用户 并使用管理员分配了台数 且有可用的MDM证书和ABM证书(公有和私有的都可以 只要有可用的就可以) 一部用来上锁的手机 链接wifi wifi必须要是2.4g频段 不要使用5gwifi 上锁…

HTTPS协议详解:从原理到流程,全面解析安全传输的奥秘

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

(done) 声音信号处理基础知识(11) (Complex Numbers for Audio Signal Processing)

参考&#xff1a;https://www.youtube.com/watch?vDgF4m0AWCgA&t1047s 似乎是因为信号处理需要使用复数&#xff0c;作者花了一节课介绍复数 据油管主所说&#xff0c;声学信号处理中引入复数的原因是&#xff1a;快速完成部分计算 这里的例子是&#xff0c;当我们做傅里…

行为型模式-命令-迭代-观察者-策略

命令模式 是什么 将一个请求封装成为一个对象, 从而可以使用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及可以撤销的操作 实例 请求封装成为对象 //用来声明执行操作的接口 public abstract class Command { protected Receiver receiver; public Comma…

物联网智能项目全面解析

目录 引言 一、物联网概述 1.1 什么是物联网 1.2 物联网的历史与发展 二、物联网智能项目分类 三、关键组件与技术 3.1 传感器和执行器 3.2 连接技术 3.3 数据处理与分析 3.4 用户界面 四、物联网智能项目案例分析 4.1 智能家居 4.2 智慧城市 4.3 工业物联网 4.4…

react-问卷星项目(3)

项目实战 React Hooks 缓存&#xff0c;性能优化&#xff0c;提升时间效率&#xff0c;但是不要为了技术而优化&#xff0c;应该是为了业务而进行优化 内置Hooks保证基础功能&#xff0c;灵活配合实现业务功能&#xff0c;抽离公共部分&#xff0c;自定义Hooks或者第三方&am…

【Kubernetes】常见面试题汇总(五十四)

目录 120.创建 init C 容器后&#xff0c;其状态不正常&#xff1f; 特别说明&#xff1a; 题目 1-68 属于【Kubernetes】的常规概念题&#xff0c;即 “ 汇总&#xff08;一&#xff09;~&#xff08;二十二&#xff09;” 。 题目 69-113 属于【Kubernetes】的生产…

Swagger配置且添加小锁(asp.net)(笔记)

此博客是基于 asp.net core web api(.net core3.1)框架进行操作的。 一、安装Swagger包 在 NuGet程序包管理中安装下面的两个包&#xff1a; swagger包&#xff1a;Swashbuckle.AspNetCore swagger包过滤器&#xff1a;Swashbuckle.AspNetCore.Filters 二、swagger注册 在…

开源 AI 智能名片 O2O 商城小程序与抖音:品牌传播的新机遇与挑战

摘要&#xff1a;本文探讨了开源 AI 智能名片 O2O 商城小程序在品牌传播中的作用&#xff0c;以及与抖音平台相结合所带来的机遇与挑战。分析了抖音如何利用算法适配品牌调性为门店找到目标消费者&#xff0c;放大品牌势能&#xff0c;同时阐述了新品牌在抖音上进行品牌传播的优…

C++平台跳跃游戏

目录 开头程序Game.cpp源文件Player.h头文件Player.cpp源文件 程序的流程图程序游玩的效果下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。 程序 Game.cpp源文件 #include <iostream> #include "Player.h" using namespace std; void printma…

[数据集][目标检测]电力场景防震锤缺陷检测数据集VOC+YOLO格式705张1类别

重要说明&#xff1a;防震锤缺陷图片太难找&#xff0c;数据集里面存在大量单一场景图片&#xff0c;请仔细查看图片预览谨慎下载&#xff0c;此外数据集均为小目标检测&#xff0c;如果训练map偏低属于正常现象 数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径…

19.第二阶段x86游戏实战2-寻找寻路call

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

C++容器之list基本使用

目录 前言 一、list的介绍&#xff1f; 二、使用 1.list的构造 2.list iterator的使用 3.list capacity &#x1f947; empty &#x1f947;size 4.list element access &#x1f947; front &#x1f947; back 5.list modifiers &#x1f947; push_front &#x1f947; po…