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

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

目录

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.mrgr.cn/news/46272.html

相关文章:

  • 鸿蒙开发(NEXT/API 12)【蓝牙服务开发】网络篇
  • TypeScript速成班:一篇文章搞定
  • 【学术会议推荐】研究生必读:参加学术会议的十大益处|附:学术会议投稿指南,助力科研梦想!
  • 图片怎么转换成pdf格式?这几种方法操作起来很简单!
  • 【AI知识点】词嵌入(Word Embedding)
  • ​健康体检管理系统
  • 销售团队管理全面指南:从结构到流程
  • uni-app 打包成app时 限制web-view大小
  • 【MATLAB源码-第240期】基于matlab的孔雀优化算法(POA)无人机三维路径规划,输出做短路径图和适应度曲线.
  • 【优选算法】(第三十篇)
  • dvwa:文件包含、文件上传
  • 域名的命名规则有哪些?注册域名需要注意哪些?
  • 华为S5735交换机console密码重置和恢复出厂设置
  • MyBatis之ResultMap的association和collection
  • AGI时代存内计算芯片的语音识别之旅 —— 知存科技开发板体验与感悟
  • 【代码随想录Day38】动态规划Part07
  • vue路由缓存问题
  • 【springboot入门之YAML使用】
  • 非刚性点云配准 Non-rigid registration of two surfaces.SHREC 14 Human 数据集
  • 一键从想法到上线:Bolt.new重新定义全栈开发流程