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

从零开始的C++学习生活 6:string的入门使用

个人主页:Yupureki-CSDN博客

C++专栏:C++_Yupureki的博客-CSDN博客

目录

前言

1. 为什么学习string类?

1.1 C语言字符串的局限性

1.2 字符串的重要性

2. 标准库中的string类

2.1 string类基础

2.2 C++11新特性:auto和范围for

auto关键字

范围for循环

3. string基本操作

构造字符串

容量操作

4 string访问和遍历

访问

遍历

5. string的修改操作

6. string类的模拟实现

6.1 浅拷贝问题

6.2 深拷贝解决方案

结语


前言

在C++编程中,字符串处理是我们日常开发中最常见的任务之一。C语言中,我们使用字符数组和\0结尾的方式来处理字符串,但这种方式存在诸多不便:需要手动管理内存、容易发生越界访问、功能有限且不符合面向对象的思想。

C++标准库中的string类彻底改变了这一局面,它封装了字符串的存储和操作,提供了丰富而安全的接口,让我们能够更加高效、安全地处理字符串。无论是算法竞赛、日常开发还是面试求职,string类都是我们必须掌握的重要工具。

本文将全面介绍C++ string类的使用方法和实现原理,帮助大家深入理解并熟练运用这个强大的工具。

1. 为什么学习string类?

1.1 C语言字符串的局限性

在C语言中,字符串是以\0结尾的字符数组,虽然标准库提供了一系列字符串操作函数,但存在明显问题:

char str[20] = "hello";
strcat(str, " world");  // 需要确保数组足够大,否则可能越界

并且在C语言中,字符串的处理相关的函数极少。如果现在我要求你对"hello world"进行以下操作:在'e'前面插入5个'x',删除第一个'l',找到字符串中第一个'o',删除所有的' ',最后将字符串再改回"hello world"。你看到这,似乎并不是很难,但是特别麻烦。每一个要求都需要十几行的代码,如果加在一起便十分复杂。

那么string就解决了这个问题,因为集成了我们所需的几乎所有处理字符串的操作函数

1.2 字符串的重要性

https://www.nowcoder.com/practice/1277c681251b4372bdef344468e4f26e?tpId=13&&tqId=11202&rp=6&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking

https://leetcode-cn.com/problems/add-strings/

在OJ中,有关字符串的题目基本以string类的形式出现,并且在竞赛中,对于字符串的处理也十分频繁,如果在C中死板的一行行写,那么就十分低效

2. 标准库中的string类

2.1 string类基础

string为C++中十分重要的一个板块,为此我们专门在专业的C++相关文档中查阅并讲解

http://www.cplusplus.com/reference/string/string/?kw=string

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

2.2 C++11新特性:auto和范围for

auto关键字

auto让编译器自动推导变量类型,使代码更简洁

 int main(){int a = 10;auto b = a;auto c = 'a';//auto根据赋值的类型,自动推导变量的类型,因此auto的变量必须初始化auto d = func1()
}

范围for循环

使用auto简化容器遍历:

string str = "hello";
// 传统遍历
for (size_t i = 0; i < str.size(); ++i) {cout << str[i];
}// 范围for遍历
for (auto ch : str) {cout << ch;  // 自动遍历每个字符
}// 如果需要修改字符串,使用引用
for (auto& ch : str) {ch = toupper(ch);  // 将字符转为大写
}

3. string基本操作

构造字符串

string是个,因此具有构造函数

string s1;              // 空字符串
string s2("hello");     // 用C字符串构造
string s3(s2);          // 拷贝构造
string s4(5, 'A');      // "AAAAA"
string s5 = "world";    // 赋值构造

容量操作

函数名称

size(重点)   返回字符串有效字符长度

length    返回字符串有效字符长度

capacity   返回空间总大小

empty (重点)  检测字符串释放为空串,是返回true,否则返回false

clear (重点)  清空有效字符

reserve (重点)为字符串预留空间**

resize (重点)  将有效字符的个数该成n个,多出的空间用字符c填充

string str = "hello";
cout << str.size();     // 5,返回有效字符长度
cout << str.length();   // 5,与size()相同
cout << str.capacity(); // 返回总容量
cout << str.empty();    // 是否为空str.clear();            // 清空字符串
str.resize(10, 'x');    // 调整大小,多出部分用'x'填充
str.reserve(100);       // 预留空间,提高效率

4 string访问和遍历

访问

string重载了operator[],使其能够像操作数组一样利用[]来访问元素

int main ()
{std::string str ("Test string");for (int i=0; i<str.length(); ++i){std::cout << str[i];//利用[]和下标来访问元素}return 0;
}

遍历


begin和end

begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器

string str = "hello";// 迭代器
for (auto it = str.begin(); it != str.end(); ++it) {cout << *it;//从左到右访问->hello
}

rbegin和rend

rbegin获取一个字符的反向迭代器 + rend获取第一个字符的位置

string str("hello")
for (auto it = str.rbegin(); it != str.rend(); ++it) {cout << *it;//从右往左访问->olleh
}
str.push_back('!');     // 尾部添加字符

5. string的修改操作

函数名称 功能说明

push_back 在字符串后尾插字符c

str.push_back('!');     // 尾部添加字符

append  在字符串后追加一个字符串

str.append(" world");   // 追加字符串

operator+= (重点)  在字符串后追加字符串str

str += "!!!";           // 最常用的追加方式

c_str(重点) 返回C格式字符串

find(重点) 从字符串pos位置开始往找字符c/字符串,返回该字符在字符串中的位置

size_t pos = str.find("world");    // 查找子串

rfind (重点) 从字符串pos位置开始往找字符c/字符串,返回该字符在字符串中的位置

substr   在str中从pos位置开始,截取n个字符,然后将其返

if (pos != string::npos) {string sub = str.substr(pos, 5); // 截取子串
}

erase 删除子串

str.erase(5, 4);// 删除子串(从起始地点为5的位置开始删除4个字符)

6. string类的模拟实现

6.1 浅拷贝问题

浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致 多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉

class String {
private:char* _str;
public:String(const char* str = "") {_str = new char[strlen(str) + 1];strcpy(_str, str);}// 问题:默认拷贝构造是浅拷贝!~String() { delete[] _str; }
};void Test() {String s1("hello");String s2(s1);  // 浅拷贝!s1和s2指向同一内存
} // 析构时同一内存被释放两次,程序崩溃

6.2 深拷贝解决方案

如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给 出。一般情况都是按照深拷贝方式提供。

class String {
public:String(const char* str = "") {_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) {char* temp = new char[strlen(s._str) + 1];strcpy(temp, s._str);delete[] _str;_str = temp;}return *this;}~String() { delete[] _str; }private:char* _str;
};

现代写法(推荐)

class String {
public:String(const char* str = "") {_str = new char[strlen(str) + 1];strcpy(_str, str);}// 拷贝构造:利用临时对象和swapString(const String& s) : _str(nullptr) {String temp(s._str);swap(_str, temp._str);}// 赋值:参数为值传递,利用swapString& operator=(String s) {swap(_str, s._str);return *this;}~String() { delete[] _str; }private:char* _str;
};

结语

string类是C++中极其重要的组件,它让我们能够更加安全、高效地处理字符串。通过本文的学习,希望大家能够:

  1. 熟练掌握string类的各种常用接口

  2. 理解深拷贝和浅拷贝的区别及重要性

  3. 能够自己实现一个简单的string

  4. 在实战中灵活运用string解决各种字符串问题

练习建议:

  • 实现自己的String类(包含基本操作)

  • 完成leetcode上的字符串相关题目

  • 阅读标准库中string的源码实现

http://www.dtcms.com/a/461248.html

相关文章:

  • 风景网站模板济南seo关键词排名工具
  • UE5 测量 -1,长度测量:P2制作定位球与定位线,P3制作射线检测节点,P4在鼠标位置生成定位球
  • UE5 GAS GameAbility源码解析 EndAbility
  • 潍坊网站建设 潍坊做网站外贸网站服务器推荐
  • 第7章 n步时序差分(3) n 步离轨策略学习
  • 【Leetcode hot 100】35.搜索插入位置
  • Django ORM 字段查询表达式(Field lookup expressions)
  • 设计模式--组合模式:统一处理树形结构的优雅设计
  • 推荐算法学习笔记(十九)阿里SIM 模型
  • 高级网站开发工程师证书现代网站建设
  • 只能在线观看的电影网站咋么做wordpress教程 菜单
  • echarts画一个饼图
  • 基于改进YOLO算法的果园环境中障碍物识别与检测技术研究
  • 三元锂电池和磷酸铁锂电池:从原子晶格到应用哲学的深度解析
  • vscode-background 扩展的原理、配置和使用
  • 2100AI相亲(三)
  • 时钟服务器主地址
  • 瑞安学校网站建设口碑好网站建设价格
  • 自己做的网站访问不了建设网站哪些公司好
  • SpringMVC启动流程
  • HTTP 请求方法与参数上传形式的关系
  • 如何减少 Elasticsearch 集群中的分片数量
  • 当通过API发送请求的方式自动触发Jenkins job报错HTTP Status 403 – Forbidden的解决办法
  • 一个网站如何工作流程建立网站需要哪些手续
  • H3C网络设备 实验二:搭建两个局域网,使两个局域网相互通信(路由器,固定ip)
  • 临平房产做网站的公司wordpress屏蔽功能org
  • Skywalking 的本地开发配置
  • iOS 上架 App 全流程实战,应用打包、ipa 上传、App Store 审核与工具组合最佳实践
  • JavaScript核心构成与基础语法详解2
  • 邹平网站建设公司淘宝网站开始怎么做