【探索C++】string类详解

2023-09-18 20:50:06


        在C++中,字符串处理是非常重要的一部分,而stringSTL中封装的一个重要工具,用于处理字符串。它的强大功能在上上篇博客中有些许讲解,那么本文将介绍C++中字符串的基本概念以及string类的构造方法,让你彻底理解和掌握C++中的string类

一. C++中字符串的概念

        在C++中,字符串是文本数据的重要形式,用于存储和处理文本信息。C++中,有多种方式来表示字符串,其中最常用的是使用string。掌握好string类对新手是及其重要的。

1.1 string

   string是C++标准模板库(STL)中封装的一个类,用于表示和操作字符串。它是对字符数组(char数组)或字符指针(char *)的封装,提供了一系列的成员函数(后文马上也会介绍到详细的常见成员用法等),简化了字符串的操作。

1.2 string类的优势

        与传统的字符数组或字符指针相比,string有以下优势:

  • 内存管理string自动管理字符串的内存,不需要手动释放内存或担心内存越界问题。

  • 操作简便string提供了丰富的成员函数,使得字符串的操作变得更加简单和灵活。

  • 安全性:由于内存管理由string自动处理,可以减少许多常见的内存错误

1.3 输入字符串

        需要注意的是,如果使用 cin 来输入字符串,它会在遇到空格时停止输入。如果需要获取包含空格的输入,应使用getline函数,如下所示:

string name;
getline(cin, name); // 通过getline获取包含空格的输入

        getline函数的具体用法呢上一篇博客中也有详细介绍,感兴趣请翻阅查看。

二. string字符串的构造

        现在让我们来看一下如何构造string字符串

2.1 默认无参构造函数

   string具有默认无参构造函数,可以用来创建一个空的字符串对象,如下所示:

string str; // 创建一个空的字符串对象

2.2 有参构造函数

   string也提供了有参构造函数,用于根据给定的内容创建字符串对象。以下是一些示例:

  • 使用字符串字面值创建字符串对象:
string str1("hello world"); // 使用字符串字面值创建字符串对象
string str2 = "hello world"; // 另一种方式
  • 使用字符和重复次数创建字符串对象:
string str3(10, 'A'); // 创建包含10个'A'字符的字符串

2.3 拷贝构造函数

    string还具有拷贝构造函数,可以通过复制已有的字符串对象来创建新的字符串对象,如下所示:

string str4 = str1; // 使用拷贝构造函数创建新的字符串对象
string str5(str2); // 另一种使用拷贝构造函数的方式

三. 重载运算符

        学习C语言时大家肯定对重载没有太多印象,如果你能记起 & 是被重载的那么你的C语言是扎实的,它既可以是按位与操作符又是取地址操作符;那么在C++中,string重载了许多操作符使得字符串的操作更加方便和灵活。下面我们将介绍一些常见的操作符重载函数。

3.1 赋值运算符(=)

        赋值运算符(=)被重载用于将一个字符串赋值给另一个字符串。例如:

string str1 = "hello world"; // 使用赋值运算符将一个字符串赋值给str1
string str2;
str6 = str1; // 使用赋值运算符将str4的值赋给str2
cout << "str2 = " << str2 << endl;

3.2 左移运算符(<<)

        左移运算符(<<)被重载用于将字符串输出到输出流,通常用于输出到控制台。例如:

string str1 = "hello world";
cout << "str1 = " << str1 << endl; // 使用左移运算符将str1输出到控制台

3.3 右移运算符(>>)

        右移运算符(>>)被重载用于从输入流中读取字符串。例如:

string str1;
cin >> str1; // 使用右移运算符从输入流中读取字符串

3.4 数组下标操作符([])

        数组下标操作符([])被重载,使得可以通过下标访问字符串中的字符。例如:

string str1 = "hello world";
char c = str1[2]; // 使用数组下标操作符访问字符串的第三个字符(下标从0开始)
cout << "c = " << c << endl; // 输出 c = l

3.5 加法运算符(+)

        加法运算符(+)被重载用于将两个字符串连接起来。例如:

string str1 = "hello ";
string str2 = "world";
string str3;
str3 = str1 + str2; // 使用加法运算符连接两个字符串

3.6 加法赋值运算符(+=)

        加法赋值运算符(+=)被重载用于将一个字符串与另一个字符串连接并将结果赋值给原字符串。例如:

string str1 = "hello ";
string str2 = "world";
str1 += str2; // 使用加法赋值运算符连接并赋值

3.7 关系运算符(==、!=、<、>、<=、>=)

        关系运算符(==!=<><=>=)被重载,用于比较两个字符串的大小关系。例如:

string str1 = "apple";
string str2 = "banana";
if (str1 < str2) {
    cout << "str1 小于 str2" << endl;
} else {
    cout << "str1 大于等于 str2" << endl;
}

注意:

        只要你的类(stig字符串)里面,只要对运算符有做重载,你都可以直接去用这个运算符,如果没有,则会报以下这个错误:
 

no match for‘operator|’         //operator是关键,表示后面的这个运算符没有做重载

四、C++的string成员函数

        之前的一篇博客已经详细的讲解了string类强大的功能,那么今天我们来看看该类下到底有多少常用的成员函数,用于操作和处理字符串。

4.1 length()size()

        返回字符串的长度,即字符的个数。

string str = "hello";
int len = str.length();
 // 或 int len = str.size();

4.2 empty()

        检查字符串是否为空,返回true表示为空,false表示非空。

string str = "hello";
bool isEmpty = str.empty(); // 返回 false

4.3 clear()

        清空字符串的内容,使其成为空字符串。

string str = "hello";
str.clear(); // str现在是一个空字符串

4.4 substr(start, length)

        返回从指定位置开始的指定长度的子字符串。

string str = "hello world";
string sub = str.substr(6, 5); // sub = "world"

4.5 find(substring)

        在字符串中查找子字符串,并返回第一次出现的位置(索引),如果未找到则返回string::npos

string str = "hello world";
size_t pos = str.find("world"); // pos = 6

4.6 replace(start, length, new_str)

        用新字符串替换指定位置的子字符串。

string str = "hello world";
str.replace(6, 5, "there"); // str = "hello there"

4.7 append(new_str)+=

        将新字符串追加到原字符串的末尾。

string str = "hello";
str.append(" world"); // str = "hello world"
// 或者
string str1 = "hello";
string str2 = " world";
str1 += str2; // str1 = "hello world"

4.8 insert(pos, new_str)

        在指定位置插入新字符串。

string str = "hello";
str.insert(3, " there"); // str = "hello there"

4.9 erase(start, length)

        删除指定位置的一段字符。

string str = "hello world";
str.erase(6, 5); // str = "hello "

4.10 compare(str2)

  与另一个字符串比较,返回0表示相等,正数表示大于,负数表示小于。

string str1 = "apple";
string str2 = "banana";
int result = str1.compare(str2); // result < 0,因为"apple"小于"banana"

     

4.11 at()

        获取字符串的单个字符。

string str1("hello");
string str2("world");
char c=str1.at(4);    //获取下标为4的这个字符
cout <"c ="<c <endl;
str2.at(0)='h';    //更改第0个字符为'h'
cout <"str2 ="<str2 <endl;

4.12 assign()

        字符串的赋值。

string str1("hello world");
string str2;
str2.assign(str1);
cout <"str2 ="<str2 <endl;

string str3;
str3.assign(str1,0,5);    //从0开始,赋值5个
cout <"str3 ="<str3 <endl;

4.13 swap()

        字符串的交换。

string str1("hello");
string str2("world");
cout <"str1 ="<str1 <endl;
cout <"str2 ="<str2 <endl;
str1.swap(str2);
cout <"str1 ="<str1 <endl;
cout <"str2 ="<str2 <endl;

练习1:将字符串中所有的小写字母和大写字母颠倒并输出。

#include <iostream>
using namespace std;

int main() {
    string str("Hello WorLD");
    
    // 遍历字符串中的每个字符
    for (int i = 0; i < str.length(); ++i) {
        // 如果字符是大写字母,将其转换为小写字母
        if (str[i] >= 'A' && str[i] <= 'Z') {
            str[i] += 32;
        }
        // 如果字符是小写字母,将其转换为大写字母
        else if (str[i] >= 'a' && str[i] <= 'z') {
            str[i] -= 32;
        }
    }

    cout << str << endl;

    return 0;
}


练习2:编写一个程序,去掉给定字符串中重复的字符,比如goooooogle   =>    gole。

#include <iostream>
using namespace std;

int main() {
    string str;
    cin >> str; // 从输入获取字符串,例如输入:gooooogle

    // 遍历字符串中的每个字符
    for (int i = 0; i < str.length(); ++i) {
        // 再次遍历字符串中的字符,从当前字符的下一个位置开始
        for (int j = i + 1; j < str.length(); ) {
            // 如果当前字符与后面的字符相同,就删除后面的字符
            if (str[i] == str[j]) {
                str.erase(j, 1); // 删除重复字符(假设删除字符的后一个还是这个字符)
            } else {
                ++j;
            }
        }
    }

    cout << str << endl; // 输出移除重复字符后的字符串

    return 0;
}

        更多C/C++语言Linux系统数据结构ARM板实战相关文章,关注专栏:

   手撕C语言

            玩转linux

                    脚踢数据结构

                            系统、网络编程

                                     探索C++

                                             6818(ARM)开发板实战

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉🎉🎉感谢关注🎉🎉🎉
更多推荐

软件测试/测试开发丨利用人工智能ChatGPT自动生成架构图

点此获取更多相关资料简介架构图通过图形化的表达方式,用于呈现系统、软件的结构、组件、关系和交互方式。一个明确的架构图可以更好地辅助业务分析、技术架构分析的工作。架构图的设计是一个有难度的任务,设计者必须要对业务、相关技术栈都非常清晰才能设计出来符合需求的架构图。实践演练1.有明确的业务的需求:业务需求必须要清晰不能模棱

ArcGIS 10.3软件安装包下载及安装教程!

【软件名称】:ArcGIS10.3【安装环境】:Windows【下载链接】:链接:https://pan.baidu.com/s/1K5ab7IHMYa23HpmuPkFa1A提取码:oxbb复制这段内容后打开百度网盘手机App,操作更方便哦软件解压码点击原文获取:ArcGIS10.3软件安装包下载及安装教程软件介绍:

网络初识

一IP地址概念:IP地址主要用于表示网络主机、其他网络设备(如路由器)的网络地址。简单说,IP地址用于定位主机的网络地址格式IP地址是一个32为的二进制数,通常被分割为4个“8位二进制数“(也就是4个字节),通常用”点分十进制“的方式来表示,即a.b.c.d的形式(a,b,c,d都是0~255之间的十进制整数)。如:1

mysql 备份和还原 mysqldump

因window系统为例在mysql安装目录中的bin目录下cmd备份备份一个数据库mysqldump-uroot-hhostname-p数据库名>备份的文件名.sql备份部分表mysqldump-uroot-hhostname-p数据库名[表[表2…]]>备份的文件名.sql##多个表空格隔开,中间没有逗号备份单表的部

数据工程中的单元测试完全指南

在数据工程领域中,经常被忽视的一项实践是单元测试。许多人可能认为单元测试仅仅是一种软件开发方法论,但事实远非如此。随着我们努力构建稳健、无错误的数据流水线和SQL数据模型,单元测试在数据工程中的价值变得越来越清晰。本文带你深入探索如何将这些成熟的软件工程实践应用到数据工程中。1单元测试的重要性在数据工程的背景下,采用单

【Android取证篇】华为设备跳出“允许USB调试“界面方法的不同方法

【Android取证篇】华为设备跳出"允许USB调试"界面方法的不同方法华为设备在鸿蒙OS3系统之后,部分设备启用"允许USB调试"方式会有所变化,再次做个记录—【蘇小沐】1.实验环境系统版本Windows11专业工作站版22H2(22621.2134);HarmonyOS3;(一)【Android取证篇】华为设备无法

dockerfile文件详解(常用命令)

在编写Dockerfile时,考虑以下最佳实践:最小化镜像大小:尽量使用轻量级的基础镜像,并在构建过程中尽量减少不必要的层。合理使用缓存:Docker会尝试重用缓存的层,如果一个步骤发生变化,后续步骤将失去缓存。因此,将频繁变化的步骤放在最后,以便充分利用缓存。清理不必要的文件:在构建镜像时,删除不必要的文件和缓存以减

【从0学习Solidity】13. 继承

【从0学习Solidity】13.继承博主简介:不写代码没饭吃,一名全栈领域的创作者,专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构,分享一些项目实战经验以及前沿技术的见解。关注我们的主页,探索全栈开发,期待与您一起在移动开发的世界中,不断进步和创造!本文收录于不写代码没饭吃的学习汇报系列,大家有兴趣的可

Java实现图书管理系统

一、分析有主要对象二、整理思路三、框架的搭建四、操作内部的具体实现一、分析主要对象我们做的图书管理系统的目的,是可以根据不同的用户,所能执行的操作不一样,主要有增删查改图书等操作,选择这些不同的操作会给我们反馈不一样的结果,而我们的主要对象就有书、书架、用户、操作这四个对象。二、整理思路书里面可以放书名、作者、价格等变

VS2019的SDL2项目配置

库下载SimpleDirectMediaLayer-Homepage对于Windows下使用VS2019开发的选手,应该直接选VC后缀了。VS目录配置首先VS2019创建一个空项目,新加入一个源文件,代码如下:/*ThissourcecodecopyrightedbyLazyFoo'Productions2004-20

【C++】topk问题

解决topK问题是寻找给定数据集中前K个最大或最小的元素。常见有三种算法:堆排序维护一个大小为K的最小(或最大)堆。遍历数据集,将元素插入堆中,如果堆大小超过K,则删除堆顶元素。遍历结束后,堆中剩余的K个元素就是前K个最小(或最大)的元素。时间复杂度:O(NlogK),其中N为数据集大小。示例代码如下:#include

热文推荐