C++之string相关(入门级)

news2024/10/9 16:32:27

目录

1. 引言

2. C语言中的字符串与C++ string类的对比

3. C++ string类概述

3.1 string类的构造与初始化

3.2 string类的基本操作

3.3 string类的查找和替换

3.4 string类的遍历

4. C++11新特性在string类中的应用

5. string类的模拟实现

5.1 浅拷贝和深拷贝

浅拷贝示例:

深拷贝示例:

6. 总结与扩展阅读


1. 引言

C++ string是用于字符串操作的重要工具之一。相比于C语言中以字符数组形式存储的字符串,C++的string类在功能和安全性上有了显著提升。由于string封装了字符串的存储与操作,我们在使用时不必过多担心底层内存管理问题。这在编程中减少了潜在的内存泄漏与越界访问风险,是现代C++开发的核心之一

在这篇文章中,我们将深入探讨string类的各种功能,包括基本操作、常用接口、内部实现机制以及模拟string类的基本方法,最终让您更深入地理解和掌握string类的用法和原理。


2. C语言中的字符串与C++ string类的对比

在C语言中,字符串以字符数组的形式存储,以\0结尾。C语言的字符串操作依赖于手动管理内存,程序员需要使用诸如strcpy()strcat()等函数来操作字符串。

C语言字符串的基本操作

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

int main() {
    char str1[20] = "Hello, C!";
    char str2[20];
    
    // 字符串复制
    strcpy(str2, str1);
    printf("str2: %s\n", str2);
    
    // 字符串连接
    strcat(str1, " World");
    printf("str1: %s\n", str1);
    
    // 字符串长度
    printf("Length of str1: %lu\n", strlen(str1));
    
    return 0;
}

问题:C语言的字符串在操作上较为复杂且容易出错。例如,如果目标数组str2的空间不足以容纳被复制的内容,程序将面临越界的风险。

在C++中,string类避免了上述问题,自动管理字符串的内存,支持运算符重载和面向对象的方法调用。C++中的字符串可以这样初始化并操作:

C++ string类的基本操作

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

int main() {
    string str1 = "Hello, C++!";
    string str2 = str1;     // 拷贝构造
    str1 += " Welcome!";    // 字符串拼接
    
    cout << "str1: " << str1 << endl;  // 输出 Hello, C++! Welcome!
    cout << "str2: " << str2 << endl;  // 输出 Hello, C++!
    
    cout << "Length of str1: " << str1.length() << endl;
    
    return 0;
}

C++优势:在C++中,string类自动管理内存,同时为字符串操作提供了更加直观和简洁的语法,这些特性极大提高了编程的安全性和开发效率。


3. C++ string类概述

C++中的string类支持多种操作,包括字符串的构造、修改、查找和遍历等。

3.1 string类的构造与初始化

string类提供了多种构造方法,可以创建空字符串、以C字符串初始化字符串或通过字符和长度创建字符串:

#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'的字符串 "aaaaa"
    
    cout << "s1: " << s1 << endl;   // 输出空字符串
    cout << "s2: " << s2 << endl;   // 输出 "Hello, C++!"
    cout << "s3: " << s3 << endl;   // 输出 "Hello, C++!"
    cout << "s4: " << s4 << endl;   // 输出 "aaaaa"
    
    return 0;
}

3.2 string类的基本操作

string类提供了访问、修改字符串的方法,如at()push_back()append()clear()等。

访问与修改字符

string s = "Hello";
cout << s[1] << endl;     // 使用[]操作符输出 'e'
cout << s.at(1) << endl;  // 使用at()输出 'e',更安全

注意at()方法在访问越界时会抛出异常,而[]操作符不会,因此在一些严格的场景中at()更加安全。

添加字符和字符串

string s = "Hello";
s.push_back('!');         // 添加单个字符
cout << s << endl;        // 输出 "Hello!"

s.append(" World");       // 添加字符串
cout << s << endl;        // 输出 "Hello! World"

清空和判断字符串

string s = "Hello";
s.clear();               // 清空字符串
cout << s.empty() << endl;  // 输出 1 (true) 表示字符串为空

3.3 string类的查找和替换

查找是string类中非常常用的操作之一,可以通过find()rfind()来在字符串中搜索特定子串或字符,并使用replace()替换指定位置的子串:

string s = "Hello, C++!";
size_t pos = s.find("C++");    // 查找子串"C++"
if (pos != string::npos) {
    s.replace(pos, 3, "World"); // 将"C++"替换为"World"
}
cout << s << endl;            // 输出 "Hello, World!"

3.4 string类的遍历

可以使用for循环或范围for进行遍历。后者在C++11中引入,使代码更简洁。

string s = "Hello";
for (char c : s) {
    cout << c << ' ';
}
cout << endl; // 输出 H e l l o

4. C++11新特性在string类中的应用

C++11引入了auto关键字和范围for循环,简化了对string类的使用。

auto关键字auto让编译器自动推断变量类型,在string类操作中尤为方便。例如在使用迭代器遍历string时:

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

int main() {
    string str = "Hello, C++11!";
    for (auto it = str.begin(); it != str.end(); ++it) {
        cout << *it << ' ';
    }
    return 0;
}

范围for循环:C++11的范围for使代码更简洁,尤其在遍历和修改字符时。

string str = "Hello, C++11!";
for (auto& ch : str) {
    if (ch == ' ') {
        ch = '_';
    }
}
cout << str << endl;   // 输出 "Hello,_C++11!"

5. string类的模拟实现

为了更好地理解string类的内部机制,我们可以模拟实现一个简化版的String类,重点在于深拷贝浅拷贝

5.1 浅拷贝和深拷贝

浅拷贝:在对象复制时,只复制对象中的指针地址,而不是复制实际内容。这会导致多个对象共享同一块内存。

深拷贝:在对象复制时,同时复制数据,从而实现每个对象都拥有独立的内存

浅拷贝示例

class String {
public:
    String(const char* str = "") {
        _str = new char[strlen(str) + 1];
        strcpy(_str, str);
    }

    // 浅拷贝的拷贝构造
    String(const String& s) {
        _str = s._str;
    }

    ~String() {
        delete[] _str;
    }

private:
    char* _str;
};

在这个例子中,当String对象销毁时,将导致内存重复释放的问题,因为多个对象共享相同的内存空间。

深拷贝示例

class String {
public:
    String(const char* str = "") {
        _str = new char[strlen(str) + 1

以下是一个简单的String类模拟,实现了深拷贝以避免资源共享问题:

#include <iostream>
#include <cstring>
#include <cassert>
using namespace std;

class String {
public:
    String(const char* str = "") {
        if (str == nullptr) {
            _str = new char[1];
            *_str = '\0';
        } else {
            _str = new char[strlen(str) + 1];
            strcpy(_str, str);
        }
    }
    
    // 深拷贝构造函数
    String(const String& s) {
        _str = new char[strlen(s._str) + 1];
        strcpy(_str, s._str);
    }
    
    // 深拷贝赋值运算符
    String& operator=(const String& s) {
        if (this != &s) {
            delete[] _str;
            _str = new char[strlen(s._str) + 1];
            strcpy(_str, s._str);
        }
        return *this;
    }
    
    ~String() {
        delete[] _str;
    }

private:
    char* _str;
};

在上述代码中,我们通过自定义的拷贝构造函数和赋值运算符,确保每个String对象都持有独立的字符串数据,避免了浅拷贝带来的潜在问题。

6. 总结与扩展阅读

C++中的string类提供了安全、便捷、功能强大的字符串操作接口。掌握string类有助于提高代码的健壮性,并能大幅减少由内存管理带来的问题。学习string类的实现和用法,对理解C++标准库以及面向对象编程具有深远意义。

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

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

相关文章

YOLO11涨点优化:注意力魔改 | 动态稀疏注意力的双层路由方法BiLevelRoutingAttention | CVPR2023

💡💡💡本文改进内容: BiLevelRoutingAttention方法对小目标检测效果比较好。可能是因为BRA模块是基于稀疏采样而不是下采样,一来可以保留细粒度的细节信息,二来同样可以达到节省计算量的目的。 💡💡💡本文改进:分别加入到YOLO11的backbone、neck、detect,助力…

ggshield:查找并修复基础设施即代码错误配置和硬编码密钥

关于ggshield ggshield是一款针对基础设施及代码的安全检测工具&#xff0c;该工具支持查找并修复 400 多种类型的硬编码敏感数据和 70 多种类型的基础设施即代码配置错误。 ggshield是一个在你的本地环境或 CI 环境中运行的 CLI 应用程序&#xff0c;可帮助你检测 400 多种类…

【JAVA开源】基于Vue和SpringBoot的知识管理系统

本文项目编号 T 074 &#xff0c;文末自助获取源码 \color{red}{T074&#xff0c;文末自助获取源码} T074&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

Android 带你玩转单元测试

前言 为什么要用到单元测试呢&#xff0c;一般开发谁会写单元测试&#xff0c;反正我认识的人都不会做&#xff0c;又耗时间&#xff0c;效果又一般&#xff0c;要是在单元测试的代码里面又出BUG的话又要改半天&#xff0c;麻烦。 但是有的时候真的是不得不用&#xff0c;比如…

YOLOv10改进策略【注意力机制篇】| 2024 SCSA-CBAM 空间和通道的协同注意模块

一、本文介绍 本文记录的是基于SCSA-CBAM注意力模块的YOLOv10目标检测改进方法研究。现有注意力方法在空间-通道协同方面未充分挖掘其潜力&#xff0c;缺乏对多语义信息的充分利用来引导特征和缓解语义差异。SCSA-CBAM注意力模块构建一个空间-通道协同机制&#xff0c;使空间注…

【科研日常】2024年计算图形学与多媒体CCF A、B类会议投稿截止日期汇总

整理了2024年多媒体方向的CCFA、B类学术会议的截稿时间&#xff0c;文末附有按月份排列的表格&#xff0c;各位同学可作为投稿参考。 A类会议 ACM MM 2024 ACM Multimedia 2024 Home (acmmm.org) Apr 8, 2024 SIGGRAPH 2024 Technical Papers | SIGGRAPH 2024 Jan 23, 202…

《深度学习》循环神经网络RNN 结构及原理解析

目录 一、关于RNN 1、传统神经网络存在的问题 2、什么是循环神经网络 3、RNN特点 二、RNN基本结构 1、RNN基本结构 2、推导方式 注意&#xff1a; 3、循环的由来 4、RNN的局限性 一、关于RNN 1、传统神经网络存在的问题 无法训练出具有顺序的数据&#xff0c;模型搭…

基于卷积神经网络的书法字体识别系统,resnet50,mobilenet模型【pytorch框架+python】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示&#xff1a; 基于卷积神经网络的书法字体识别系统&#xff0c;resnet50&#xff0c;mobilenet【pytorch框架&#xff0c;python&#xff0c;tkinter】_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷…

牛客——xay loves or与 __builtin_popcount的使用

xay loves or 题目描述 登录—专业IT笔试面试备考平台_牛客网 运行思路 题目要求我们计算有多少个正整数 yy 满足条件 x \text{ OR } y sx OR ys。这里的“OR”是指按位或运算。为了理解这个问题&#xff0c;我们需要考虑按位或运算的性质。 对于任意两个位 a_iai​ 和 b_…

如何用AI绘画工具生成中国风插画?Midjourney保持风格一致出图

如何运用AI绘画工具如Midjourney&#xff0c;生成符合我们特定要求的艺术作品是一门精进的技巧&#xff0c;尤其当你想生成具有鲜明特色的国风插画时&#xff0c;纯文本提示词的局限性常常使我们难以达到预期效果。然而&#xff0c;借助Midjourney的高级参数功能——特别是sref…

中航资本:招保万金全跌停!“人气王”创历史,半日成交突破600亿

狂奔的“牛”总算迎来“回头”。 今日是新股民入市第一天。依据我国结算的安排&#xff0c;关于10月1日&#xff08;周二&#xff09;至10月8日&#xff08;周二&#xff09;提交请求的新开证券账户&#xff0c;于10月9日&#xff08;周三&#xff09;起可用于买卖。 不过&am…

GIS、向量、文字检索... 火山引擎 ByteHouse 集成全场景分析能力

企业业务场景增多、规模扩大&#xff0c;对于底层数据架构来说&#xff0c;可能也会愈加复杂。 比如&#xff0c;某企业因自身业务发展&#xff0c;需要引入向量检索能力&#xff0c;但前期选型的技术架构并不能直接支持&#xff0c;只能重新引入向量数据库。这意味着&#xff…

JavaWeb - 9 - MySQL

数据库&#xff1a;DataBase(DB)&#xff0c;是存储和管理数据的仓库 数据库管理系统&#xff1a;DataBase Management System(DBMS)&#xff0c;操纵和管理数据库的大型软件 SQL&#xff1a;Structured Query Language&#xff0c;操作关系型数据库的编程语言&#xff0c;定…

经纬恒润荣获2024中国汽车供应链大会创新成果奖

2024年9月24日-26日&#xff0c;2024中国汽车供应链大会暨第三届中国新能源智能网联汽车生态大会在武汉隆重举办。本届大会以“新挑战、新对策、新机遇——推动中国汽车供应链可持续发展”为主题&#xff0c;集聚政府主管领导、行业专家、汽车及零部件企业精英和主流媒体&#…

这个 JavaScript API 比你想象中更强大!

大家好&#xff0c;我是 ConardLi。 今天&#xff0c;我们来聊聊一个可能被你忽视&#xff0c;而且非常强大的标准 JavaScript API - AbortController 。 在过去&#xff0c;大家在提到 AbortController 的时候&#xff0c;一般会举请求中断的例子&#xff0c;就连 MDN 给到的…

重学SpringBoot3-集成Redis(三)之注解缓存策略设置

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;三&#xff09;之注解缓存策略设置 1. 引入 Redis 依赖2. 配置 RedisCacheManager 及自定义过期策略2.1 示例代码&#xff1a;自定…

重塑能源持续亏损近22亿:今年前五个月销量下滑,产能利用率骤降

《港湾商业观察》黄懿 9月2日&#xff0c;上海重塑能源集团股份有限公司&#xff08;下称“重塑能源”&#xff09;向港交所提交上市申请书&#xff0c;委任中国国际金融香港证券有限公司、招银国际融资有限公司及法国巴黎证券&#xff08;亚洲&#xff09;有限公司为整体协调…

Linux(不同版本系统包含Ubuntu)下安装mongodb详细教程

一、下载MongoDB 在MongoDB官网下载对应的MongoDB版本&#xff0c;可以点击以下链接快速跳转到下载页面&#xff1a; mongodb官网下载地址 注意选择和自己操作系统一致的platform,可以先查看自己的操作系统 查看操作系统详情 命令&#xff1a; uname -a 如图&#xff1a;操…

海洋大地测量基准与水下导航系列之二国外海底大地测量基准和海底观测网络发展现状(下)

2004年&#xff0c;英国、德国、法国等国家在欧洲“全球环境与安全监测’(Global Monitoring for Environment and Security,GMES)观测计划倡导下制定了“欧洲海底观测网络”(European Seafoor Observatory Network,ESONET)计划。ESONET是一个多学科的欧洲卓越网络(NoE &#x…