C++ -string -常见用法1

news2024/11/23 21:30:02

博客主页:【夜泉_ly】
本文专栏:【C++】
欢迎点赞👍收藏⭐关注❤️

在这里插入图片描述

文章目录

  • 💡前言
  • 1.构造函数
    • 1.1函数原型
    • 1.2用法速览
    • 1.3详解
      • () -重点⭐
      • ( s) -重点⭐
      • ( n, c) -重点⭐
      • ( str) -重点⭐
      • ( str, pos, len)
      • ( s, n)
  • 2.容量函数
    • 2.1函数原型
    • 2.2用法速览
    • 2.3详解
      • size() -重点⭐
      • reserve() -重点⭐
      • resize() -重点⭐

💡前言

在这篇文章中,我将简单探讨 C++string 的基本用法。写这篇文章的主要目的是帮助我巩固所学的知识,同时也便于未来的复习和参考。

如果你想大致的了解string的基本用法,也可以留下来看看。

对于那些希望深入学习更多细节的读者,可以去看看这个网站:cplusplus.com,以获取更全面的参考资料。

1.构造函数

1.1函数原型

在 C++98 中,string 类提供了七种构造函数,具体的函数原型如下:

string();
string (const string& str);
string (const string& str, size_t pos, size_t len = npos);
string (const char* s);
string (const char* s, size_t n);
string (size_t n, char c);
template <class InputIterator> string  (InputIterator first, InputIterator last);

注:
函数原型中的缺省参数npos是一个为静态成员变量,类型为size_t,值为-1(整型的最大值),通常用于表示无效位置。

1.2用法速览

在众多构造函数中,以下四个是最常用的:

string s1; // 创建一个空的 string 对象
string s2("Hello World"); // 用 C 字符串初始化 string 对象
string s3(6, '6'); // 用 6 个字符 '6' 填充 string 对象
string s4(s2); // 使用 s2 拷贝构造一个新的 string 对象

此外,还有一些不太常用的构造函数:

string s5(s2, 6, 5); // 从 s2 的第 7 个字符(下标为6)开始,拷贝 5 个字符
string s6("Hello World", 5); // 用"Hello World"的前 5 个字符初始化 string 对象

至于其他构造方式,我暂时还不熟悉。

1.3详解

() -重点⭐

string s1;

调用的是默认构造函数,创造出一个空的string类对象,其字符串为空,即""
VS上的调试图:

在调试中可以看到,空的string类对象具有以下特征:

  • 初始字符串长度size0
  • 初始容量capacity15(实际为16,但最后一个用来放\0

尽管空的 string 类对象可以被打印出来,但不会显示任何内容:

cout << "s1:" << s1 << endl;
cout << "s1:" << s1 << 'a' << endl;

在这里插入图片描述

( s) -重点⭐

string s2("Hello World");

以C类型的字符串构造string类对象。

C类型的字符串就是以\0为结束标志的字符串。

VS上的调试图:
在这里插入图片描述
显然,这种构造方式有一个限制,即它无法将'\0'填入string类对象,例如:

string s2("Hello \0World"); // 此时 '\0' 之后的字符不会被存储

在这里插入图片描述

( n, c) -重点⭐

string s3(6, '6'); 

nc字符填充string类对象。
在这里插入图片描述
与用C类型的字符串构造不同,这种构造方式可以将'\0'填入string类对象:

string s3(10,'\0'); // 创建一个长度为 10 的字符串,全部填充 '\0'

在这里插入图片描述

( str) -重点⭐

string s2("Hello World");
string s4(s2);

调用的是拷贝构造函数。
在这里插入图片描述
会拷贝原string类对象的所有内容,而不是简单地拷贝 C 类型的字符串:

string s3(10,'\0'); // 创建一个长度为 10 的字符串,全部填充 '\0'
string s4(s3); // 拷贝构造,复制 s3 的内容

在这里插入图片描述

( str, pos, len)

string s2("Hello World");
string s5(s2, 6, 5);

strpos位置(指下标)开始,拷贝len个字符。
在这里插入图片描述

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

在其函数原型中,len给了一个缺省参数npos

static const size_t npos = -1;

可以看见,npos为一个静态常变量,值为-1,又因为其类型为size_t,因此,npos实际值为整型的最大值。
当传参时,不传len或传的len过大,会默认从strpos位置拷贝至结尾。

string s2("Hello World");
string s5_1(s2, 6); // 默认拷贝至字符串结束
string s5_2(s2, 6, 100); // 尝试拷贝超过实际长度,将从第 6 个字符拷贝至结束

在这里插入图片描述

( s, n)

拷贝字符串s的前n个字符。感觉比较废。

2.容量函数

2.1函数原型

size: 返回当前字符串的长度

size_t size() const;

length: 返回当前字符串的长度(与 size() 等效)

size_t length() const;

max_size: 返回字符串可以容纳的最大字符数

size_t max_size() const;

resize: 改变字符串的长度

void resize (size_t n);
void resize (size_t n, char c);

capacity: 返回当前字符串的容量

size_t capacity() const;

reserve: 预留空间

void reserve (size_t n = 0);

clear: 清空字符串

void clear();

empty: 判断字符串是否为空

bool empty() const;

shrink_to_fit: 收缩容量

void shrink_to_fit();

2.2用法速览

常用的:

string s; // 创建一个空字符串
//size:
cout << s.size() << endl; // 输出字符串的长度

//reserve:
s.reserve(100); // 预留 100 个字符的空间
cout << s.capacity() << endl; // 输出当前字符串的容量

//resize:
//1:
s.resize(5); // 调整字符串的长度为 5
cout << s.size() << endl; // 输出调整后的长度
//2:
s.resize(10,'6'); // 调整字符串的长度为 10,填充字符 '6'
cout << s << endl; // 输出字符串内容

//clear:
s.clear(); // 清空字符串内容
cout << s << endl; // 输出空字符串

不常用的:

//length:
cout << s.length() << endl; // 输出字符串的长度(与 size() 等效)

//max_size:
cout << s.max_size() << endl; // 输出字符串可以容纳的最大字符数

//capacity:
cout << s.capacity() << endl; // 输出当前字符串的容量

//empty:
cout << (s.empty() ? "String is empty" : "String is not empty") << endl; // 判断字符串是否为空

//shrink_to_fit:
s.shrink_to_fit(); // 收缩字符串的容量,释放多余的内存
cout << s.capacity() << endl; // 输出收缩后的字符串容量

2.3详解

size() -重点⭐

重点,但用法很简单。
可以返回字符串的有效字符长度。
注,并非C语言类型的字符串的长度:

string s(10,'0'); // 创建一个包含 10 个 '0' 的字符串
cout << s.size() << endl; // 输出结果将是 10

Output:

10

注意事项:

  • string类对象的size并不一定等于其容量capacity
  • 由于不知道编码方式,返回值可能不等于实际编码后的字符数量。

std::sizestd::length的用法完全一致(一般用size),文档中将它们称作同义词synonym

reserve() -重点⭐

注意区分reserve和reverse!!!

可以改变string类对象的容量capacity不会改变有效数据个数size!!!

扩容与缩容:

可简单测试一下:

string s;
size_t cap = s.capacity();
cout << "Init:" << cap << endl;
for (int i = 0; i < 200; i++)
{
	s += ' ';
	if(cap != s.capacity())
	{
		cap = s.capacity();
		cout << "capacity change : " << cap << endl;
	}
}

在这里插入图片描述

不同环境的自动扩容机制不同,VS大概是1.5倍,linux大概是2倍。

reserve手动扩容,如果提前知道要多少空间,这样做可减少自动扩容带来的消耗:

string s;
s.reserve(100);

在这里插入图片描述
VS上,一般会稍微大于你给的值,因为它有一套自己的对齐规则。
这样的实现并没有问题:

在这里插入图片描述


如果字符串有内容,一般不会缩容:

string s("1");
s.reserve(100);
s.reserve(0);
cout << s.capacity() << endl;

在这里插入图片描述
如果为空字符串(初始为空/被clear清空),可能会缩容:

string s;
s.reserve(100);
s.reserve(0);
cout << s.capacity() << endl;

string s2("Hello World!!!!!!!!!!!!!!!!");
s2.clear();
s2.reserve(0);
cout << s2.capacity() << endl;

在这里插入图片描述
reserve也有缺省参数:

void reserve (size_t n = 0);

因此: s . r e s e r v e ( ) ; s.reserve(); s.reserve(); 等价于 s . r e s e r v e ( 0 ) ; s.reserve(0); s.reserve(0);

如果有编译器,任何情况它都不缩/缩,这种实现也是对的,因为这是一个不具有约束力的请求:

在这里插入图片描述

resize() -重点⭐

可以改变string类对象的有效数据个数size,增容时可能改变容量capacity大小。
该函数提供了两个重载版本:

void resize (size_t n);
void resize (size_t n, char c);

用法:

  1. string s;
    s.resize(3,'6'); // 将字符串大小调整为 3,并用字符 '6' 填充
    

    在这里插入图片描述

    当使用void resize (size_t n, char c);增加size时,多余的部分用字符c填充。

  2. s.resize(6); // 调整大小为 6,多余部分将用 '\0' 填充
    

    在这里插入图片描述
    当使用void resize (size_t n);增加size时,多余部分默认用'\0'填充:
    在这里插入图片描述
    所以std::resize的两个重载函数应该可以合成为一个:void resize (size_t n, char c = '\0');,没这样做的原因好像是函数重载比缺省参数早出现。

  3. s.resize(0);
    

    直接变成空串,但不改变capacity
    这点感觉和std::clear完全相似。

在这里插入图片描述


希望本篇文章对你有所帮助!并激发你进一步探索编程的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!

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

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

相关文章

github 上将 stable 合并到 master 分支步骤

本地仓库分支&#xff1a;origin 远端仓库分支&#xff1a;upstream 切到非 master 分支上&#xff0c;比如 dev # 本地操作 git branch -D master git fetch upstream master::master git checkout master # 这步是拉取远端 stable 到 master 上&#xff0c;可能会出错误 # fa…

21次惊艳亮相!凯特王妃的秋季时尚造型!在时尚领域她已经无限接近戴安娜王妃

虽然凯特米德尔顿正式成为英国王室成员才刚刚十多年&#xff0c;但很难想象没有她的王室会是什么样子。毕竟&#xff0c;凭借她非凡的风格和不可否认的魅力&#xff0c;威尔士王妃在2011年迅速赢得了我们以及全世界的喜爱。 我们都喜欢关注她的项目以及她和威廉王子的爱情故事…

基于STM32的智能电能表设计

引言 本项目设计了一个基于STM32的智能电能表&#xff0c;能够实时测量电压、电流、功率以及累计的电能消耗。通过ADC模块采集电压和电流信号&#xff0c;结合功率计算算法&#xff0c;系统可以精准地监控家庭或工业设备的电能消耗。该智能电能表还支持远程数据传输和本地数据…

Krea.ai正式发布AI视频集合站:Luma、Runway与可灵的深度整合

引言 在数字内容日益丰富的今天&#xff0c;视频制作的需求呈现爆发式增长。为了满足创作者对高效、创新视频工具的渴求&#xff0c;Krea.ai推出了全新的AI视频集合站。此平台整合了多款领先工具&#xff0c;如Luma、Runway、可灵和Minimax&#xff0c;为用户提供一站式的视频…

【等号绕过】

简介 一、大小于号绕过 上面的<>是不等于的意思 测试注入点&#xff1a; id1 正常输入id1 测试是否有注入id1 and 11%23 提示hacker~ 被过滤了id1 and 1%23 没有被过滤&#xff0c;说明是被过滤&#xff0c;但是没有输出id1 and 1%23 页面有输…

25四非网安保研回忆录(北航网安/东南网安/重大计科等)

目录 0 个人情况 1 夏令营 西南大学计科 西南交通大学计科 重庆大学计科 2 预推免 东南大学网安 北京航空航天大学网安 3 写在最后 0 个人情况 计算机类比较强的四非&#xff0c;信安专业rank1&#xff0c;六级540&#xff0c;竞赛十几个&#xff0c;无论文&#xff…

【Linux网络编程】网络基础 | Socket 编程基础

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

2.13寸电子墨水屏HINK-E0213+esp8266

记录好数字 2.13寸电子墨水屏HINK-E0213esp8266 声明:大部分资料来源于微雪电子http://微雪电子-官网 https://www.waveshare.net/ 前言 很久以前买的一块电子墨水屏,运气很好,这个型号HINK-E0213资料很全,而且微雪官网也有相关电路资料http://2.13inch e-Paper HAT - Waves…

java邮件发送

文章目录 前言一、开启SMTP邮箱配置二、spring-mail1.引入依赖2.yml配置3.使用二、hutool-mail1.引入hutool2.在resource下新增mail.setting3.使用总结前言 发送邮件: 目前比较简单的有两种方式实现: spring-mailhuool-mail现在看下两种方式 一、开启SMTP邮箱配置 两种方式…

mysql查询2张表连接列名一样的情况

people表&#xff1a; person表&#xff1a; SELECT * FROM person LEFT JOIN people on people.idperson.id 查询的结果id(1)和name(1)说明列名重复 SELECT person.id,person.name,people.id as pid,people.name as pname FROM person LEFT JOIN people on people.idperso…

Linux shellcheck工具

安装工具 通过linux yum源下载&#xff0c;可能因为yum源的问题找不到软件包&#xff0c;或者下载的软件包版本太旧。 ShellCheck的源代码托管在GitHub上(推荐下载方式)&#xff1a; GitHub - koalaman/shellcheck: ShellCheck, a static analysis tool for shell scripts 对下…

10.高级存储过程技巧(10/10)

高级存储过程技巧博客大纲 引言 在现代数据库管理系统中&#xff0c;存储过程作为提升数据操作效率和安全性的关键工具&#xff0c;已被广泛应用于各种数据库操作中。存储过程是一组为了完成特定功能的SQL语句集合&#xff0c;这些语句在数据库中被保存、编译和优化&#xff0…

Chromium 前端window对象c++实现定义

前端中window.document window.alert()等一些列方法和对象在c对应定义如下&#xff1a; 1、window对象接口定义文件window.idl third_party\blink\renderer\core\frame\window.idl // https://html.spec.whatwg.org/C/#the-window-object// FIXME: explain all uses of [Cros…

【原创】java+springboot+mysql在线课程学习网设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

陪诊小程序搭建:打造便利的陪诊环境

陪诊行业作为一个新兴行业&#xff0c;随着老龄化的严重&#xff0c;在近几年中需求量日益旺盛。陪诊师为大众的就医提供了极大的便利性&#xff0c;在看病难、医疗资源紧张方面发挥了积极作用。 在陪诊行业的快速发展下&#xff0c;陪诊小程序为行业带来了便捷的模式&#xf…

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器 源链接&#xff1a;https://threehub.cn/#/codeMirror?navigationThreeJS&classifyshader&idchinaFlag 国内站点预览&#xff1a;http://threehub.cn github地址: https://github.com/z2586300277/three-ce…

数学建模算法与应用 第6章 微分方程建模及其求解方法

目录 6.1 微分方程建模概述 6.2 发射卫星与三阶火箭建模 Matlab代码示例&#xff1a;火箭发射模拟 6.3 微分方程数值解法 Matlab代码示例&#xff1a;欧拉法与龙格-库塔法 6.4 放射性废料的处理 Matlab代码示例&#xff1a;放射性衰变 6.5 初值问题的Matlab数值求解 习…

Java项目:149 基于SSM的毕业设计管理系统

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 毕业设计管理系统 介绍 毕业设计是本科教育的最后一个环节&#xff0c;整个过程包括课题拟定与审核、师生双选、开题报告、文档审核、中期检查、毕业答…

C++ 比大小

//输入两个可能有前导 0 的大整数&#xff0c;a,b请输出他们谁大谁小#include <iostream> #include <string> #include <string.h> using namespace std; #define M 100005 int main() {char a[M], b[M];char *pa, *pb;pa a;pb b;cin >> a >> …

Linux的pinctrl和gpio子系统

上一章我们编写了基于设备树的 LED 驱动&#xff0c;但是驱动的本质还是没变&#xff0c;都是配置 LED 灯所使用的 GPIO 寄存器&#xff0c;驱动开发方式中硬件初始化这一部分和裸机基本没啥区别。Linux 是一个庞大而完善的系统&#xff0c;尤其是驱动框架&#xff0c;像 GPIO …