探索 C++ 标准库:std::string 库函数用法示例

news2024/11/27 8:26:58

目录

引言

一、构造函数

1.1 string()

1.2 string (const string& str)

1.3 string (const string& str, size_t pos, size_t len = npos)

1.4 string (const char* s)

1.5 string (const char* s, size_t n)

1.6 string (size_t n, char c)​

 二、容量相关函数

2.1 size_t size() const

2.2 size_t length() const

2.3 size_t max_size() const

2.4 void resize (size_t n)&&void resize (size_t n, char c)

2.5 size_t capacity() const

2.6 void reserve (size_t n = 0)

2.7 void clear()

2.8 bool empty() const

2.9  void shrink_to_fit()

 三、修改操作相关函数

3.1  string& operator+=

3.2 append 

3.3 void push_back (char c)

3.4 assign 

3.5 insert

3.6  erase

3.7 replace

 3.8 void swap (string& str)

3.9 void pop_back()

结语


引言

在现代编程世界中,字符串是不可或缺的基本元素,而 C++ 标准库中的 std::string则是在处理和操作字符串时的得力工具。无论是从构造字符串开始,还是进行子串提取、连接、比较等操作,std::string 为开发者提供了广泛的功能,使字符串处理变得更加高效和便捷。

在本文中,我们将深入探索 std::string 类的多种功能和用法示例,帮助您更好地理解如何利用这些功能解决实际编程问题。无论您是初学者还是有经验的开发者,这些示例都将为您打开掌握字符串处理技巧的大门。

一、构造函数

1.1 string()

创建空字符串(默认构造函数) 

 1.2 string (const string& str)

 ✨拷贝构造函数

 1.3 string (const string& str, size_t pos, size_t len = npos)

✨子串构造函数

参数解释 

 pos

一个表示起始位置的无符号整数值。

指定从源字符串的哪个位置开始提取子串,从 0 开始计数。

len(可选)

一个表示提取的子串的长度的无符号整数值。

默认情况下,如果没有指定该参数,将提取从起始位置 pos 到源字符串的末尾的全部内容

如果指定了 len,则提取从位置 pos 开始的连续 len 个字符。

如果len参数设置得很大,超过了源字符串的长度,构造函数会自动截取到源字符串的末尾为止,确保不会超出源字符串的范围。

1.4 string (const char* s)

✨从 C 字符串构造

1.5 string (const char* s, size_t n)

✨使用指向字符数组的指针以及长度来创建新字符串对象

1.6 string (size_t n, char c)

✨填充构造函数

 二、容量相关函数

2.1 size_t size() const

✨获取有效字符长度

 2.2 size_t length() const

 ✨获取有效字符长度(同size函数)

2.3 size_t max_size() const

✨ 返回字符串对象的最大可能大小(以字符为单位)

 2.4 void resize (size_t n)&&void resize (size_t n, char c)

void resize(size_t n)

这个函数用于将字符串的大小更改为指定的大小 n,并且不提供填充字符。当新大小 n 大于当前大小时,它会将字符串扩展为新大小并用空字符填充。如果 n 小于当前大小,超出部分的字符将被截断。如果 n 等于当前大小,则不会执行任何操作。

void resize(size_t n, char c)

这个函数也用于将字符串的大小更改为指定的大小 n,但是提供了一个填充字符 c。如果新大小 n 大于当前大小,字符串将增长并用填充字符 c 填充。如果 n 小于当前大小,超出部分的字符将被截断。如果 n 等于当前大小,则不会执行任何操作。

当n大于当前字符串容量时会自动进行扩容。

2.5 size_t capacity() const

 ✨用于获取字符串对象当前分配的内存容量(以字符为单位)

 2.6 void reserve (size_t n = 0)

  ✨用于保留字符串对象的内存以容纳至少 n 个字符

✨解释一下此处容量为30的问题

笔者使用的Clion进行演示。创建空字符串或有效字符小于等于15时,编译器都会开辟15个字节的空间,当使用该函数进行扩容时,该编译器自动扩容2倍,因为该函数说明也是至少开辟到n个空间(如果n大于当前capacity),不同编译器、平台实现有所不同。

✨若n小于当前容量则不做处理

如果传递给 reserve 函数的参数 n 值比当前字符串对象的容量小,那么函数会忽略该请求,不会进行任何内存调整或重新分配。

2.7 void clear()

 ✨用于清空字符串对象的内容,将其变为空字符串,分配的内存空间仍然保留。

2.8 bool empty() const

 ✨用于检查字符串对象是否为空,即其中是否没有字符。

#include <iostream>
#include <string>

int main() {
    std::string emptyString = ("");
    std::string nonEmptyString =("Hello, World!");

    // 使用 empty() 函数检查字符串是否为空
    if (emptyString.empty()) {
        std::cout << "Empty String is empty!" << std::endl;
    } else {
        std::cout << "Empty String is not empty!" << std::endl;
    }

    if (nonEmptyString.empty()) {
        std::cout << "Non-Empty String is empty!" << std::endl;
    } else {
        std::cout << "Non-Empty String is not empty!" << std::endl;
    }

    return 0;
}

2.9  void shrink_to_fit()

✨用于请求字符串对象释放多余的内存,使其内存使用与字符串的大小相匹配。

✨不保证一定会减小内存,因为内存管理取决于底层实现。

✨Clion在此情况就饿没有做处理,或许是因为它默认15字节为最小容量。

那让我们来试试扩大容量再试试

处理啦对吧!

 三、修改操作相关函数

3.1  string& operator+=

 ✨用于将一个字符串或字符序列追加到当前字符串的末尾。

string& operator+= (const string& str)

这个运算符将另一个 std::string 对象 str 追加到当前字符串的末尾,并返回当前字符串的引用。相当于将 str 的内容添加到当前字符串的末尾。

string& operator+= (const char* s)

这个运算符将以空字符结尾的 C 风格字符串(字符数组) s 追加到当前字符串的末尾,并返回当前字符串的引用。相当于将 s 的内容添加到当前字符串的末尾。

string& operator+= (char c)

这个运算符将字符 c 追加到当前字符串的末尾,并返回当前字符串的引用。

#include <iostream>
#include <string>

int main() {
    std::string myString = ("Hello");

    // 使用 += 运算符将另一个字符串追加到当前字符串
    std::string appendString = " there";
    myString += appendString;

    // 使用 += 运算符将 C-风格字符串追加到当前字符串
    const char* cStyleStr = " and";
    myString += cStyleStr;

    // 使用 += 运算符将字符追加到当前字符串
    char c = '!';
    myString += c;

    std::cout << "Modified String: " << myString << std::endl;

    return 0;
}

3.2 append 

 append函数+=运算符重载的效果类似。解释其中部分。

 string& append(const string& str, size_t subpos, size_t sublen)

这个函数将另一个 std::string 对象 str 中从索引 subpos 开始的长度为 sublen 的子串追加到当前字符串的末尾,并返回当前字符串的引用。

sublen 太大时, 函数可能会引发未定义的行为或错误。在使用这个函数时,需要确保 subpossublen 的值不会越界到超出 str 的有效范围。

string& append(const char* s, size_t n)

这个函数将 C 风格字符串(字符数组) s 中的n 个字符追加到当前字符串的末尾,并返回当前字符串的引用。

#include <iostream>
#include <string>

int main() {
    std::string myString = ("Hello");
    
    // 使用不同的 append 函数将不同内容追加到当前字符串
    myString.append(" there");  // 追加另一个字符串
    myString.append(" and more", 0, 4);  // 追加子串
    myString.append("!", 1);  // 追加单个字符
    myString.append(2, '*');  // 追加重复字符
    
    std::cout << "Modified String: " << myString << std::endl;
    
    return 0;
}

3.3 void push_back (char c)

✨用于将一个字符 c 追加到字符串的末尾,扩展字符串的内容。

#include <iostream>
#include <string>

int main() {
    std::string myString("Hello");

    // 使用 push_back 函数将字符追加到当前字符串
    myString.push_back(' ');  // 添加一个空格字符
    myString.push_back('W');  // 添加字符 'W'

    std::cout << "Modified String: " << myString << std::endl;

    return 0;
}

3.4 assign 

✨可以理解为赋值函数。其中大部分参数与append函数类似,此处不赘述。

✨append是在末尾追加,assign时相当于重新赋值。

#include <iostream>
#include <string>

int main() {
    std::string myString;

    // 使用 assign 函数分配不同内容给当前字符串
    myString.assign("Hello");  // 分配字符串
    std::cout << "String after assign: " << myString << std::endl;

    myString.assign(" there", 1, 4);  // 分配子串
    std::cout << "String after assign (substring): " << myString << std::endl;

    myString.assign("World");  // 重新分配字符串
    std::cout << "String after re-assign: " << myString << std::endl;

    myString.assign(3, '!');  // 分配重复字符
    std::cout << "String after assign (repeat): " << myString << std::endl;

    return 0;
}

 3.5 insert

 ✨参数亦与之前介绍的函数类似,相信读者能够很容易理解。

#include <iostream>
#include <string>

int main() {
    std::string myString = ("Hello World");

    // 使用 insert 函数在不同位置插入内容
    myString.insert(5, " there");  // 在位置 5 插入字符串
    std::cout << "String after insert: " << myString << std::endl;

    myString.insert(11, "!", 1);   // 在位置 11 插入字符 '!'
    std::cout << "String after insert (char): " << myString << std::endl;

    myString.insert(0, 3, '*');    // 在位置 0 插入重复字符 '*'
    std::cout << "String after insert (repeat): " << myString << std::endl;

    return 0;
}

3.6  erase

✨用于从字符串中删除从位置 pos 开始的长度为 len 的字符序列。 

✨默认值 npos 表示删除从 pos 开始的所有字符直到字符串的末尾。

#include <iostream>
#include <string>

int main() {
    std::string myString("Hello, World!");
    
    // 使用 erase 函数删除字符序列
    myString.erase(5, 7);  // 从位置 5 开始,删除 7 个字符
    
    std::cout << "Modified String: " << myString << std::endl;
    
    return 0;
}

如果 len 的值超出了要删除的字符序列的实际长度,erase 函数会从指定位置开始删除所有可用的字符,直到字符串的末尾。这不会引发错误,函数会尽量删除尽可能多的字符,而不会超出字符串的范围。

3.7 replace

string& replace(size_t pos, size_t len, const string& str)

在位置 pos 处开始,用另一个 std::string 对象 str 的内容替换长度为 len 的字符序列,并返回当前字符串的引用。

string& replace(size_t pos, size_t len, const char* s)

在位置 pos 处开始,用以空字符结尾的 C 风格字符串(字符数组) s 替换长度为 len 的字符序列,并返回当前字符串的引用。

string& replace(size_t pos, size_t len, const char* s, size_t n)

在位置 pos 处开始,用 C 风格字符串(字符数组) s 中的前 n 个字符替换长度为 len 的字符序列,并返回当前字符串的引用。

如果 len 的值超出了要替换的字符序列的实际长度replace 函数会从指定位置开始尽可能多地替换字符,直到字符串的末尾。这不会引发错误,函数会尽量替换尽可能多的字符,而不会超出字符串的范围。

如果 len 的值小于要替换的字符序列的实际长度,函数会从指定位置开始替换指定长度的字符序列,然后字符串会收缩,被删除的字符序列会被新的字符序列取代。

#include <iostream>
#include <string>

int main() {
    std::string myString("Hello, World!");

    // 使用 replace 函数替换内容,len 超出了字符串的实际长度
    myString.replace(7, 20, "Universe");  // 从位置 7 开始,替换 20 个字符(超出实际长度)
    std::cout << "String after replace: " << myString << std::endl;

    myString.assign("Hello, World!");
    myString.replace(7, 5, "Hi, Universe");  // 从位置 7 开始,替换 5 个字符(字符串长度对应不上)
    std::cout << "String after replace (len mismatch): " << myString << std::endl;

    return 0;
}

 3.8 void swap (string& str)

 ✨用于交换当前字符串对象与另一个字符串对象 str 之间的内容。

#include <iostream>
#include <string>

int main() {
    std::string firstString = "Hello";
    std::string secondString = "World";

    std::cout << "Before swap:" << std::endl;
    std::cout << "First String: " << firstString << std::endl;
    std::cout << "Second String: " << secondString << std::endl;

    // 使用 swap 函数交换两个字符串的内容
    firstString.swap(secondString);

    std::cout << "\nAfter swap:" << std::endl;
    std::cout << "First String: " << firstString << std::endl;
    std::cout << "Second String: " << secondString << std::endl;

    return 0;
}

如果交换的两个字符串的容量不同,swap 函数会将容量一并交换,从而使得交换后的字符串对象具有对应的容量。这意味着,在交换后,字符串对象的内容和容量都会被交换。 

#include <iostream>
#include <string>

int main() {
    std::string firstString = "Hello";
    std::string secondString = "World!!xxxxxxxxxxxxxxxxxx";

    std::cout << "Before swap:" << std::endl;
    std::cout << "First String: " << firstString << ", Capacity: " << firstString.capacity() << std::endl;
    std::cout << "Second String: " << secondString << ", Capacity: " << secondString.capacity() << std::endl;

    // 使用 swap 函数交换两个字符串的内容和容量
    firstString.swap(secondString);

    std::cout << "\nAfter swap:" << std::endl;
    std::cout << "First String: " << firstString << ", Capacity: " << firstString.capacity() << std::endl;
    std::cout << "Second String: " << secondString << ", Capacity: " << secondString.capacity() << std::endl;

    return 0;
}

3.9 void pop_back()

✨用于从字符串的末尾移除一个字符,缩小字符串的长度。

#include <iostream>
#include <string>

int main() {
    std::string myString = "Hello";

    std::cout << "Before pop_back: " << myString << std::endl;

    // 使用 pop_back 函数移除字符串末尾的字符
    myString.pop_back();

    std::cout << "After pop_back: " << myString << std::endl;

    return 0;
}

结语

掌握了C++的“字符串大法”,让你的程序丰富多彩!😎 通过std::string类,你可以玩转连接、查找、插入、删除等操作,为你的代码增添绚丽色彩。无论你是刚入门还是老手,掌握这些技巧都将让你在编程的舞台上更加游刃有余。感谢阅读本文,愿你用“字符串魔法”创造出令人惊艳的程序世界!🚀

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

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

相关文章

剑指offer11-20

文章目录 11.旋转数组的最小数字12.矩阵中的路径13.机器人的运动范围15.二进制中1的个数16.数值的整数次方17.打印从1到最大的n位数&#xff08;待写&#xff09;18.删除链表的节点19.正则表达式匹配&#xff08;好难&#xff09;20. 没意义算了 11.旋转数组的最小数字 肯定不是…

【Git】—— 标签管理

目录 &#xff08;一&#xff09;理解标签 1、作用 &#xff08;二&#xff09;创建标签 &#xff08;三&#xff09;操作标签 1、删除标签 2、推送标签 3、删除远程标签 &#xff08;一&#xff09;理解标签 标签 tag &#xff0c;可以简单的理解为是对某次 commit 的…

C++11时间日期库chrono的使用

chrono是C11中新加入的时间日期操作库&#xff0c;可以方便地进行时间日期操作&#xff0c;主要包含了&#xff1a;duration, time_point, clock。 时钟与时间点 chrono中用time_point模板类表示时间点&#xff0c;其支持基本算术操作&#xff1b;不同时钟clock分别返回其对应…

Jenkins 监控dist.zip文件内容发生变化 触发自动部署

为Jenkins添加plugin http://xx:xx/manage 创建一个任务 构建触发器 每3分钟扫描一次&#xff0c;发现指定文件build.zip文件的MD5发生变化后 触发任务

脚本一键生成通用接口,一分钟实现增删改查

直接使用无需看此配置 快速生成通用接口业务配置 &#xff1a; https://blog.zysicyj.top/2023/08/14/快速生成通用接口业务配置 一、插件安装 二、脚本 关注绿色聊天软件【程序员朱永胜】回复&#xff1a;1013 下载 三、使用 拷贝到扩展目录下 修改mybatisCodehelper.vm 修改i…

【爱书不爱输的程序猿】CPOLAR+HFS,低成本搭建NAS

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 通过HFS低成本搭建NAS&#xff0c;并内网穿透实现公网访问 - cpolar 极点云 前言1.下载安装cpolar1.1 设置HFS访客1.2 虚拟文件系统 2. 使用cpolar建立一条内网穿透数据隧道2.1 保留…

强化学习 PPO算法和代码

PPO 效果 字体找不到 ubuntu python findfont: Font family ‘Alibaba PuHuiTi 3.0’ not found. shell 清除缓存&#xff1a; rm ~/.cache/matplotlib -rf到这里下载 阿里巴巴普惠体3.0 https://fonts.alibabagroup.com/ 然后安装字体 PPO import matplotlib from mat…

​​C++多态​​

目录 1. 多态的概念 2. 多态的定义及实现 多态的构成条件 虚函数 虚函数的重写 特例 override 和 final 1. final&#xff1a;修饰虚函数&#xff0c;表示该虚函数不能再被重写 2.override: 检查派生类虚函数是否重写了基类某个虚函数&#xff0c;如果没有重写编译报错…

【数据结构】二叉树篇|超清晰图解和详解:二叉树的最近公共祖先

博主简介&#xff1a;努力学习的22级计算机科学与技术本科生一枚&#x1f338;博主主页&#xff1a; 是瑶瑶子啦每日一言&#x1f33c;: 你不能要求一片海洋&#xff0c;没有风暴&#xff0c;那不是海洋&#xff0c;是泥塘——毕淑敏 目录 一、题目二、题解三、代码 一、题目 …

Stable Diffusion +EbSynth应用实践和经验分享

Ebsynth应用 1.安装ffmpeg 2.安装pip install transparent-background,下载模型https://www.mediafire.com/file/gjvux7ys4to9b4v/latest.pth/file 放到C:\Users\自己的用户名.transparent-background\加一个ckpt_base.pth文件 3.秋叶安装ebsynth插件,重启webui 填写项目基本…

线段树-模板-区间查询-区间修改

【模板】线段树 2 传送门&#xff1a;https://www.luogu.com.cn/problem/P3373 题单&#xff1a;https://www.luogu.com.cn/training/16376#problems 题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面三种操作&#xff1a; 将某区间每一个数乘上 x x x&a…

FPGA学习——驱动WS2812光源并进行动态显示

文章目录 一、WS2812手册分析1.1 WS2812灯源特性及概述1.2 手册重点内容分析1.2.1 产品概述1.2.2 码型及24bit数据设计 二、系统设计2.1 模块设计2.2 模块分析2.2.1 驱动模块2.2.1 数据控制模块 三、IP核设置及项目源码3.1 MIF文件设计3.2 ROM IP核调用3.3 FIFO IP核调用3.4 项…

机器学习-特征选择:如何使用递归特征消除算法自动筛选出最优特征?

一、引言 在实际应用中&#xff0c;特征选择作为机器学习和数据挖掘领域的重要环节&#xff0c;对于提高模型性能和减少计算开销具有关键影响。特征选择是从原始特征集中选择最相关和最具区分力的特征子集&#xff0c;以提高模型的泛化能力和可解释性。 特征选择在实践中具有以…

算法笔试 java 输入输出练习

在线编程题刷题训练 所有答案 scancer函数的用法 输入输出总结top&#xff01;&#xff01;&#xff01;&#xff01; java如何调用函数&#xff08;方法&#xff09; java刷acm的各种输入输出 vscode配置java环境 子函数的调用&#xff0c;直接定义一个static子函数调用就…

人工智能任务1-【NLP系列】句子嵌入的应用与多模型实现方式

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能任务1-【NLP系列】句子嵌入的应用与多模型实现方式。句子嵌入是将句子映射到一个固定维度的向量表示形式&#xff0c;它在自然语言处理&#xff08;NLP&#xff09;中有着广泛的应用。通过将句子转化为向量…

ARM(汇编指令)

.global _start _start:/*mov r0,#0x5mov r1,#0x6 bl LoopLoop:cmp r0,r1beq stopsubhi r0,r0,r1subcc r1,r1,r0mov pc,lr*/ mov r0,#0x1mov r1,#0x0mov r2,#0x64bl Loop Loop:cmp r0,r2bhi stopadd r1,r1,r0add r0,r0,#0x01mov pc,lr stop:B stop.end

Android Ble蓝牙App(五)数据操作

Ble蓝牙App&#xff08;五&#xff09;数据操作 前言正文一、操作内容处理二、读取数据① 概念② 实操 三、写入数据① 概念② 实操 四、打开通知一、概念二、实操三、收到数据 五、源码 前言 关于低功耗蓝牙的服务、特性、属性、描述符都已经讲清楚了&#xff0c;而下面就是使…

vue自定义指令动态绑定

在企业微信侧边栏应用中&#xff0c;给dialog添加了拖拽功能&#xff0c;但是因为dialog高度超过了页面高度&#xff0c;所以高度100%时拖拽有个bug--自动贴到窗口顶部而且企业侧边栏宽高都有限制&#xff0c;拖拽效果并不理想&#xff0c;所以就想缩小dialog再进行拖拽。 拖拽…

(一)掌握最基本的Linux服务器用法——了解Linux服务器基本的使用方法、常用命令。

1、掌握最基本的Linux服务器用法 1、了解Linux服务器基本的使用方法、常用命令。 1、Linux系统简介 略 2、服务器连接方法 1、SSH远程终端&#xff0c;Windows可以使用xshell软件。 2、PuTTY主要用来远程连接服务器&#xff0c;缺点是功能单一&#xff0c;只是一个客户端&…

Tomcat+Http+Servlet

文章目录 1.HTTP1.1 请求和响应HTTP请求&#xff1a;请求行请求头请求体HTTP响应&#xff1a;响应行&#xff08;状态行&#xff09;响应头响应体 2. Apache Tomcat2.1 基本使用2.2 IDEA中创建 Maven Web项目2.3 IDEA中使用Tomcat 3. Servlet3.1 Servlet快速入门3.2 Servlet执行…