C++:string的介绍

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合面向对象的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

所以在C++的STL库中提供了更加方便的string类。


string

string的常见构造

默认构造函数:string()

  • 创建一个空字符串对象。
  • 示例:
string str;

拷贝构造函数:string(const string& str)

  • 创建一个字符串对象,内容为另一个字符串对象str的拷贝。
  • 示例:
 string str1("hello");
 string str2(str1); // "hello"

重载构造函数:string(const string& str, size_t pos, size_t len = npos)

  • 创建一个字符串对象,内容为字符串对象str的pos位置开始的len个字符。
  • 示例:
  •  string str1("hello"); 
     string str2(str1, 1, 3); // "ell:
  • 注意:当不传入第三个参数时,其默认为npos,这个值是size_t的最大储存值,可以理解为是无穷大,也就是说,当不传入第三个参数,其会从pos位置开始拷贝到结束。

重载构造函数:string(const char* s)

  • 创建一个字符串对象,内容为字符串s
  • 示例:
  • string str("hello");
    
  • 由于单参数构造函数支持类型转换,也可以写为:
    string str = "hello";

重载构造函数:string(const char* s, size_t n)

  • 创建一个字符串对象,内容为字符串s的前n个字符。
  • 示例:
string str("hello", 3); //"hel"

重载构造函数:string(size_t n, char c)

  • 创建一个由n个字符c组成的字符串对象。
  • 示例:
string str(5, 'a'); // "aaaaa"

string的输入输出
operator<<

string<<进行了重载,我们可以直接对string对象使用<<,此时会输出这个string对象的字符串值。

示例:

string s1 = "hello world";
string s2 = " csdn";

cout << s1 << endl; //"hello world"
cout << s1 << s2 << endl; //"hello world csdn"
c_str

string还提供了一个函数,用于读取string对象中的字符串。

string s = "hello world";
cout << s.c_str() << endl; // "hello world"

c_str的返回值是一个字符串,而<<对于字符串的输出机制是遇到'\0'中止输出。而string类重载的<<输出机制则是完整输出整个字符串,如果遇到'\0',会把'\0'一起输出。 

 看一个案例:

string s = "hello world \0 csdn";
cout << s.c_str() << endl; // "hello world "
cout << s << endl; // "hello world 0 csdn"
operator>>

同样的,string也对>>进行了重载,我们可以使用>>输入字符串。

string s1;
string s2;

cin >> s1 >> s2; // 输入"hello world"
cout << s1 << endl; // "hello"
cout << s2 << endl; // "world"

但是如果我们输入的字符串中包含空格,那么>>就不是很好用。

由于输入字符串时,遇到空格会中止读取,所以包含空格的字符串不能用这个方式输入,此时就要用getline了. 

getline

getline可以获取一整行的字符串,包括空格,只有遇到换行符的时候才会中止。
不过要注意getline不是string类的成员函数,但是是string头文件的普通函数。
所以使用时不需要使用对象.getline()这样的格式,而是直接使用。

其第一个参数是istream的对象,比如cin
第二个参数是输入到的string对象。
第三个参数决定遇到什么字符的时候停止读取,默认值为'\n',即换行时停止读取。

示例:

string s;

getline(cin, s); // "hello world csdn"
cout << s << endl; // "hello world csdn"

string访问及遍历
operator[ ] & at

operator[ ] 和 at都是通过下标访问的成员函数,两者作用几乎一致。

示例:

string s = "hello world";

cout << s[2] << endl; // 'l'
cout << s[8] << endl; // 'r'

 示例:

string s = "hello world";

cout << s.at(2) << endl; // 'l'
cout << s.at(8) << endl; // 'r'

两者的参数完全一致,即pos下标,传入这个参数后,输出下标位置的字符。此外,他们各自都提供了const版本的重构,用于const对象。
两者唯一的区别就是越界的情况:
operator[ ]越界时,会通过assert报错,直接中止程序。
at越界时,会抛出异常。 

font & back

font 和 back用于返回字符串的首尾字符。

要注意,其返回值为引用返回char&,所以对其修改时,是会影响到原先的字符串的。


如果我们想遍历一个字符串,可以通过operator[ ] 或者 at,利用for循环来遍历,但是STL库还提供了迭代器,用于遍历对象。

迭代器
begin & end

在C++的string类中,beginend是两个成员函数,用于返回字符串的起始和结束迭代器。

 begin函数返回一个迭代器,该迭代器指向字符串的第一个字符。可以使用解引用运算符*获取迭代器指向的字符。例如,*str.begin()将返回字符串中的第一个字符。

 end函数返回一个迭代器,该迭代器指向字符串结尾的下一个位置。因此end()函数返回的迭代器不指向字符串中的任何字符。可以将end函数返回的迭代器与其他迭代器进行比较,以确定迭代器是否已达到字符串的末尾。

演示如何使用beginend函数遍历字符串中的字符并输出它们:

string str = "Hello World";
  
// 使用begin()和end()函数遍历字符串中的字符
string::iterrtor it = str.begin()
while(it != str.end())
{
	cout << *it;
	++it;
}

平常可以直接用auto来代替这个类型。

所以以上代码可以写为:

string str = "Hello World";
  
// 使用begin()和end()函数遍历字符串中的字符
auto it = str.begin()
while(it != str.end())
{
	cout << *it;
	++it;
}

rbegin & rend

迭代器不仅支持正向遍历,还支持反向遍历,此时就需要反向迭代器rbegin,rend了。其中r代表reverse,反转的意思。

 rbegin是一个反向迭代器,用于指向容器的最后一个元素,并向前迭代。rendrbegin的逆操作。rbegin返回容器的最后一个元素的迭代器,而rend返回容器的第一个元素之前的位置的迭代器,这是一个越界的位置,同样不允许修改。

string s1 = "54321";

string:reverse_iterator rit = s.begin();

while (rit != str.rend()) {
	cout << *rit << " ";
	++rit;
}
范围for

范围for循环也适用于string,其本质是基于迭代器的循环。

string s = "hello world";

for(auto ch : s)
{
	cout << ch;
}

string的容量操作
size & length&capacity

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

length返回当前字符串的长度。

capacity函数用于返回字符串的当前容量(当前可以存储的最大字符数)。

两者的作用完全一致,没有区别,那么为什么STL要设计两种方式来返回string对象的长度呢?

这是因为早期的string还不属于STL,使用length来表达长度,当string进入STL后,为了与其他的数据结构保持一致,都使用size来表示长度,于是又增加了一个size。

clear&empty

在string类中,clear函数用于清空字符串内容,并将字符串的长度设置为0。

empty函数用于检查一个字符串是否为空,即字符串中是否没有任何字符。该函数返回一个bool类型的值。

reserve

 reserve是一个用来预留字符串容量的方法。

reserve方法的目的是为了避免频繁的内存分配和释放操作,提高程序的效率。当我们使用string对象时,由于字符串的长度是可变的,所以在进行增删改等操作时,可能会导致内存重新分配,这会带来一定的时间开销。

为了避免这种情况,我们可以使用reserve方法来预先分配足够的内存空间。                     

resize

resize函数用于改变字符串的大小。它可以增加或减少字符串的长度。

resize函数有两个参数,第一个参数是新的字符串长度,第二个参数是填充字符(可选)。

如果新的长度小于当前长度,则字符串会被截断。如果新的长度大于当前长度,则字符串会自动增加大小,并用指定的填充字符填充空白部分,如果没有选定字符,则默认用\0填充。

 要注意的是,就算使用resizesize缩小,capacity容量大小不会减小,而是保持原本的大小。


string的修改操作
push_back

push_back函数用于将字符添加到字符串的末尾。它接受一个字符作为参数,并将其追加到字符串的末尾。

注意:push_back函数只接受一个字符作为参数,如果传递一个字符串或其他类型的参数,将会引发编译错误。

append

string类中的append方法用于将一个字符串追加到另一个字符串的末尾。它有多个重载版本,可以接受不同类型的参数作为输入。

基本使用:

string str1 = "Hello";
string str2 = " World!";
    
// 使用append方法将str2追加到str1的末尾
str1.append(str2);
    
cout << str1 << endl;  // 输出 "Hello World!"

append方法还可以接受其他类型的参数作为输入,例如const char*charstd::stringstd::initializer_list<char>等。 

 

operator+=

operator+=是用于将一个字符串追加到另一个字符串的末尾的运算符重载。

根据其三个重载可以看出来,operator+=可以追加string对象,字符串,字符三种类型,功能全面,语法简单,比appendpush_back好用的多。

insert

insert函数可以用于在字符串中插入字符、子串或其他类型的数据。

通过函数重载可以看出,我们可以插入字符,字符串,string对象等。

插入字符串:

string str = "Hello, world!";

// 在指定位置插入字符串
str.insert(5, "!!!"); // 在位置5插入"!!!"
cout << str << endl;

输出结果为:Hello!!!, world!

 插入字符:

string str = "Hello, world!";

// 在指定位置插入字符串
str.insert(5, 3, '!'); // 在位置5插入3个'!'
cout << str << endl;

输出结果为:Hello!!!, world!

 注意:插入字符时,第二个参数是插入字符的个数,哪怕只插入一个字符,这个值也不能缺省

erase

erase函数可以用来删除字符串中的字符或子字符串。 

首先,我们来看一个简单的示例,删除字符串中的一个字符:

string str = "Hello World";
str.erase(4); // 删除第5个字符,即空格
cout << str << endl; // 输出 "HelloWorld"

删除字符串中的一个子字符串:

string str = "Hello World";
str.erase(6, 5); // 从第7个字符开始,删除5个字符,即"World"
cout << str << endl; // 输出 "Hello"

除了上述两种用法外,erase函数还可以接受迭代器作为参数,用来删除指定范围内的字符或子字符串。

string str = "Hello World";
string::iterator start = str.begin() + 6; // 第7个字符的迭代器
string::iterator end = str.begin() + 11; // 第12个字符的迭代器
str.erase(start, end); // 删除从第7个字符到第12个字符的子字符串,即"World"
cout << str << endl; // 输出 "Hello "

replace

replace函数用于在字符串中替换指定的子字符串。

string str = "Hello, World!";
    
cout << "原始字符串: " << str << endl;
    
    // 使用replace函数替换字符串
str.replace(str.find("World"), 5, "Universe");
    
cout << "替换后的字符串: " << str << endl;

输出结果应为:

原始字符串: Hello, World!
替换后的字符串: Hello, Universe!

swap

swap函数用于交换两个string对象之间的内容。

string str1 = "Hello";
string str2 = "World";
 
str1.swap(str2);
    
cout << "After swap:" << endl;
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;

std中的swap()函数:

string str1 = "Hello";
string str2 = "World";
    
swap(str1, str2);
    
cout << "After swap:" << std::endl;
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;

在这个例子中,我们使用了std命名空间中的swap函数,将str1str2的内容进行了交换。输出的结果与前一个例子是一样的。

但是std中的swap将两个对象完全交换了,这个过程创建了string类型的中间变量。

 而string中的swap并没有完全交换对象,只是交换了两个对象的指针,以及值,并没有创建string类型的中间变量。所以对于string对象,使用string自带的swap效率会更高。


string的查找操作
find

find函数用于在字符串中查找子字符串的第一次出现。

find函数接受两个参数:
待查找的子字符串 str 或者字符c
开始搜索的位置 pos(可选,默认值为0)                        

返回值:

  • 如果找到了指定子串,返回它在原字符串中第一次出现的位置。
  • 如果未找到指定子串,返回string::npos
string str = "Hello World";
string subStr = "World";

// 使用find函数查找子字符串的位置
size_t index = str.find(subStr);

cout << "子字符串在位置 " << index << " 处被找到" << endl;

refind

rfind用于在字符串中寻找指定子串的最后一次出现的位置,或者说是倒着查找。

rfind函数接受两个参数:
待查找的子字符串 str 或者字符c
开始搜索的位置 pos(可选,默认为string::npos

返回值:

  • 如果找到了指定子串,返回它在原字符串中最后一次出现的位置。
  • 如果未找到指定子串,返回string::npos
sub_str

substr用于提取字符串的子串。该函数可以接受两个参数,起始索引位置和子串的长度。

string str = "Hello, world!";

// 提取从索引位置3开始的子串
string sub1 = str.substr(3);

// 输出子串
cout << sub1 << endl; // 输出为 "lo, world!"

// 提取从索引位置7开始长度为5的子串
std::string sub2 = str.substr(7, 5);

// 输出子串
cout << sub2 << endl; // 输出为 "world"

 输出结果为:

lo, world!
world

可以看到,substr() 函数成功提取了指定位置和长度的子串,并将其存储在新的字符串变量中。

find_first_of & find_first_not_of

find_first_of函数用于在字符串中查找第一个与指定字符序列中的任意字符匹配的字符的位置。

 find_first_of函数有多个重载形式,其中最常用的形式如下:

size_t find_first_of (const string& str, size_t pos = 0) const;

这个函数接受一个字符串参数str,并从指定的位置pos开始搜索。find_first_of函数会在调用对象的字符串中查找第一个与str中的任意字符匹配的字符,并返回其位置。如果找不到匹配的字符,则返回string::npos

string str = "Hello World";
string chars = "aeiou";

// 在str中查找第一个出现在"aeiou"中的字符
size_t pos = str.find_first_of(chars);
 
cout << "第一个元音字母出现在位置:" << pos << endl;
cout << "字符为:" << str[pos] << endl;

输出结果为:

第一个元音字母出现在位置:1
字符为:e

 

 

 

 

 

 

 

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RocketMQ如何保证消息的顺序性?

和Kafka只支持同一个Partition 内的消息的顺序性一样,RocketMQ中的也提供了基于队列(分区)的顺序消费。即同一个队列内的消息可以做到有序,但是不同队列内的消息是无序的! 当我们作为MQ生产者需要发送顺序消息时,需要在send方法中,传入一个MessageQueueSelector。 Mes…

Media-Download-Helper 完整部署说明

Media-Download-Helper 完整部署说明 前排提示&#xff1a;由于使用到了 Telegram、Google 等服务&#xff0c;所以当前方案不建议国内用户使用&#xff01; 基于 docker 安装 qbittorrent WebUI 使用 docker 安装 qbittorrent 非常简单&#xff0c;教程也非常非常多&#xff…

安卓7原生相机切到视频崩溃

目录 1、查看日志 2、分析日志、提取重点 3、寻找解决方法 author daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 daisy.skye_嵌入式,Linux,Qt-CSDN博客daisy.skye擅长嵌入式,Linux,Qt,等方面的知识https://blog.csdn.net/qq_40715266?typeblog 1、查看日志 由于安…

格行随身WiFiVS华为天际通VS飞猫U8真实测评大PK,随身WiFi哪个牌子最好用?随身WiFi怎么选?

如今随身WiFi界格行、华为、飞猫三足鼎立&#xff0c;被称为随身WiFi界的“三国杀”&#xff0c;今天&#xff0c;我这个江湖百晓生就来给大家揭秘&#xff0c;究竟谁才是随身网络之王&#xff1f;你准备好围观了吗&#xff1f; 先说说华为天际通随身WiFi&#xff0c;这位老大哥…

今日arXiv最热大模型论文:北大发布,通过上下文提示,让大模型学习一门新的语言

在人工智能领域&#xff0c;大语言模型&#xff08;LLMs&#xff09;的发展已经取得了显著的进步&#xff0c;它们在处理高资源语言方面表现出色。然而&#xff0c;对于资源较少的语言&#xff0c;尤其是极低资源语言&#xff0c;这些模型的支持却显得力不从心。这些语言往往缺…

【C++庖丁解牛】C++内存管理 | new和delete的使用以及使用原理

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1. C/C内存分布2. C语…

方法中单独使用return关键字

一、return关键字的单独使用 二、示例代码 public class ReturnDemo {public static void main(String[] args) {chu(10,0);chu(10,2);}public static void chu(int a,int b){if (b 0) {System.out.println("除法出错&#xff0c;除数不能为零");return;}System.ou…

无处不在的便捷:D咖无人售卖咖啡机在公共场所的应用探索

在繁忙的现代生活中&#xff0c;无人售卖咖啡机作为一项便捷的服务&#xff0c;正逐渐在公共场所得到广泛应用。本文将探讨D咖无人售卖咖啡机在公共场所的应用场景和优势。 一、无人售卖咖啡机的应用场景 写字楼&#xff1a;写字楼内工作人员需要在繁忙的工作中寻找便捷的饮品解…

【center-loss 中心损失函数】 参数与应用

文章目录 前言简单总结一下参数对比解释参数权重衰减&#xff08;L2正则化&#xff09;动量其他参数运行 前言 之前我们已经完全弄明白了中心损失函数里的代码是什么意思&#xff0c;并且怎么用的了&#xff0c;现在我们来运行它。 论文&#xff1a;https://ydwen.github.io/…

【数学+前缀和】第十四届蓝桥杯省赛C++ A组《平方差》(c++)

【问题描述】 给定 L,R&#xff0c;问 L≤x≤R 中有多少个数 x 满足存在整数 y,z 使得 xy的平方−z的平方。 【输入格式】 输入一行包含两个整数 L,R&#xff0c;用一个空格分隔。 【输出格式】 输出一行包含一个整数满足题目给定条件的 x 的数量。 【数据范围】 对于 40% 的…

创建RAID0,RAID5并管理,热备盘,模拟故障

目录 1. RAID介绍以及mdadm安装 1.1 安装mdadm工具 2. 创建raid0 2.1 环境准备 2.2 使用两个磁盘创建RAID0 2.3 查看RAID0信息 2.4 对创建的RAID0进行格式化并挂载 2.5 设置成开机挂载 2.6 删除RAID0 3. 创建raid5 3.1 环境准备 3.2 用3个磁盘来模拟R…

【C++杂货铺】详解string

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 为什么学习string &#x1f4c1; 认识string&#xff08;了解&#xff09; &#x1f4c1; string的常用接口 &#x1f4c2; 构造函数 &#x1f4c2; string类对象的容量操作 &#x1f4c2; string类对象的访问以及遍历操…

(MATLAB)应用实例13-时域信号的频谱分析

采用傅里叶变换来计算存在噪声的适于信号频谱。 假设数据采样频率为1000Hz&#xff0c;一个信号包含两个正弦波&#xff0c;频率50Hz、120Hz&#xff0c;振幅0.7、1&#xff0c;噪声为零平均值的随机噪声&#xff0c;采用FFT方法分析其频谱。 clearFs 1000; …

分享axios+signalr简单封装示例

Ajax Axios Axios 是一个基于 promise 网络请求库&#xff0c;作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。 从浏览器创建 XMLHttpReque…

kafka 可视化工具

kafka可视化工具 随着科技发展&#xff0c;中间件也百花齐放。平时我们用的redis&#xff0c;我就会通过redisInsight-v2 来查询数据&#xff0c;mysql就会使用goland-ide插件来查询&#xff0c;都挺方便。但是kafka可视化工具就找了半天&#xff0c;最后还是觉得redpandadata…

一招教你优化TCP提高大文件传输效率

在当今企业的数据传输实践中&#xff0c;传统的传输控制协议&#xff08;TCP&#xff09;在处理大型文件传输时&#xff0c;其固有的可靠性和复杂性有时会导致效率不足。为了提升大文件传输的效率&#xff0c;对TCP进行优化成为了一个关键任务。 TCP传输的可靠性是其核心优势&a…

Kubernetes-2

Kubernetes学习第二天 k8s-21、Kubernetes的核心组件2、pod2.1、什么是pod 3、3种启动pod的方式3.1、命令行启动pod3.1.1、执行下面命令&#xff0c;背后发生了什么&#xff1f; 3.2、启动一个pod背后发生了什么3.3、使用yml文件3.3.1、标准的pod3.3.2、使用部署控制器启动pod3…

windows部署腾讯tmagic-editor01-Hello world

之前写过一篇使用yarn实现的https://blog.csdn.net/qq_36437991/article/details/133644558&#xff0c;后面的两个没有写&#xff0c;这次准备重新实现 环境 pnpm 8.15.1 node 18.19.0 创建vue项目 pnpm create vitecd hello-world pnpm install执行pnpm dev启动项目 安…

[PTA] 分解质因子

输入一个正整数n&#xff08;1≤n≤1e15&#xff09;&#xff0c;编程将其分解成若干个质因子&#xff08;素数因子&#xff09;积的形式。 输入格式: 任意给定一个正整数n&#xff08;1≤n≤1e15&#xff09;。 输出格式: 将输入的正整数分解成若干个质因子积的形式&#…

TypeScript 基础(一)

目录 一、概述 二、开发环境 三、数据类型 1.boolean 2.number 3.string 4.Array 5.type 6.tuple 7.enum 8.any 9.null / undefined 10.never 11.object 结束 一、概述 TypeScript 是一种由微软开发的开源编程语言。它是 JavaScript 的一个超集&#xff0c;这意…