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

{ C++ } —— string类的使用

 一、auto关键字

        在介绍string之前,我们先来介绍一下auto,auto是一个自动推导类型的关键字

auto x = 3;//推导为int
auto x = 'a';//推导为char

       在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型 指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期 推导而得。 用auto声明指针类型时,用auto和auto*没有任何区别但用auto声明引用类型时则必须加& 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际 只对第一个类型进行推导,然后用推导出来的类型定义其他变量。 auto不能作为函数的参数,可以做返回值,但是建议谨慎使用 auto不能直接用来声明数组 

由此引出了

  范围for 

      范围for 对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此 C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围 内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。 范围for可以作用到数组和容器对象上进行遍历 范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到。 

二、string类常用接口

      (一)string类对象的构造

      string类对象可以空构造,也可以传一个字符串又或是另一个string类对象来进行构造和拷贝构造,也可以传n个字符构造。

#include<iostream>
#include<string>
using namespace std;int main()
{string s1;//空构造string s2("hello world");//C-string构造string s3(10,'a');//n个字符构造return 0;
}

      (二)string类对象的容量操作

      有时我们想要直到我们目前对象中有多少个有效数据,有时候我们又想知道当前对象底层申请了多大的空间我们就可以做如下操作++++++

int main()
{//string s1;//空构造//string s2("hello world");//C-string构造//string s3(10,'a');//n个字符构造string s1("hello world");s1.size();//返回字符串有效数据的个数(不包括\0)s1.capacity();//s1底层开辟容量的大小(不包括\0,实际开的多加1)

      有时我们想要改变size的个数,提前初始化好一块空间,或者是将size缩小到某个数,则可以

s1.resize(5);//将有效数据个数变为n个,如果比当前有效数据个数少,则删除多的数据,多则有可能扩容,默认填充\0,也可以自己给想要填的字符)
s1.resize(20, 'x');//将有效数据个数变为n个,如果比当前有效数据个数少,则删除多的数据,多则有可能扩容,默认填充\0,也可以自己给想要填的字符)

       有时我们想要清空所有有效数据,并判断是否空没空则可以

s1.empty();//检测字符串是否为空串,是返回true,不是返回false
s1.clear();//清空有效数据

       有时我们想要提前开好一块空间,避免频繁扩容效率低下则可以

s1.reserve(100);//提前开多大空间

      有时我们再完成字符串的输入后,想要让多余的空间释放,则可以

s1.shrink_to_fit();//将空间大小缩到size个(一定会缩,但不一定缩到正好size个,不具有强制约束力)

      (三、string类对象的访问及遍历操作)

      我们想要访问一个字符串类对象里面的任意一个位置只需要用方括号的形式即可访问到,他会返回第pos位置字符的引用

      迭代器方式遍历string对象

	string::iterator it = s1.begin();//[s1.begin(),s1.end());while (it != s1.end()){cout << (*it) << ' ';it++;}cout << endl;string::reverse_iterator it1 = s1.rbegin();//反着遍历while (it1 != s1.rend()){cout << (*it1) << ' ';it1++;}cout << endl;return 0;
}

      (四、string类对象的修改操作) 

      我们想要尾插一个字符可以用push_back接口,尾插字符串或者另一个string类对象可以用operator+= 和append 

	///*s1.push_back('x');*/s1.append("hello world", 3);//从0开始追加三个s1.append("hello world", 3, 5);//从第三个下标开始追加5个s1.append(10, 'x');//追加10个xs1.append(s2, 3, 5);//s1.append(s2);s1 += 'x';

       我们想要查找某个字符或者字符串可以用find接口

  

	size_t pos = s1.find('e');

std::string::find

string (1)
size_t find (const string& str, size_t pos = 0) const;
c-string (2)
size_t find (const char* s, size_t pos = 0) const;
buffer (3)
size_t find (const char* s, size_t pos, size_t n) const;
character (4)
size_t find (char c, size_t pos = 0) const;

      rfind则是从后往前寻找字符或者是字符串或者是类对象。(默认从最后一个有效数据开始找)

      substr是从一个串中指定范围返回一个字串

      replace则是将某个位置开始长度为n的字符替换成别的字符

string s1("hello world");
size_t pos = s1.rfind('w',s1.size() - 3);
s1.replace(pos, 1, "**");//从pos位置替换1个字符变成**
cout << pos << endl;
cout << s1 << endl;

      erase是从第pos个位置删除len个字符

sequence (1)
 string& erase (size_t pos = 0, size_t len = npos);
character (2)
iterator erase (iterator p);
range (3)
     iterator erase (iterator first, iterator last);
string s1("hello world");
size_t pos = s1.rfind('w',s1.size() - 3);
s1.replace(pos, 1, "**");//从pos位置替换1个字符变成**
s1.erase(0, 1);//从下标为0删除一个字符,删除h

    assign是一个赋值接口

    由于assign返回的是string& 当然也可以这么玩连续赋值。 

string s3 = s2.assign(s1, 2, 3);//相当于s2 = s1;// string s3 = s2;

     find_first_of是一个查找是否含有给出字符串的字符,当遇到给的字符串中的任意一个字符时返回该字符下标,find_last_of是从后往前进行查找。

    find_first_not_of是查找给出字符串以外的字符,并返回遇到给出字符串以外的字符的下标当遇到的时候,find_last_not_of是反向查找。

 

hello的e下标为1,在我们给出的字符串“aeiou”当中。

还有一个非成员函数operator+,可以用两个字符串相加,他们的字符串会拼接起来构造一个新string对象。不会影响他们自身。

string s1("hello world");
string s2;
s2.assign(s1, 2, 3);
cout << s2 << endl;
string s3 = s2.assign(s1, 2, 3);
size_t pos = s1.find_first_of("aeiou");
cout << pos << endl;
string s4 = s1 + s2;

  对于我们输入字符串如果不想让空格作为分隔符,想让空格也作为string对象的一部分读进去那就可以用getline。

 

这里的delim就是分隔符,默认以\n作为分隔符,遇到这个\n就会读完一个string对象。也可以自己设置分隔符。

http://www.xdnf.cn/news/13874.html

相关文章:

  • 1年从零通过CISSP!
  • Day52 Python打卡训练营
  • LaViDa:基于扩散模型的多模态大模型,速度超越next-token范式
  • 海思网卡框架介绍
  • Application with id application_xxx doesn‘t exist in RM解决方法
  • 基于mapreduce的气候分析系统设计与实现
  • 创客匠人:为知识变现与 IP 打造赋能
  • 纯血HarmonyOS ArKTS NETX 5 打造小游戏实践:狼人杀(介绍版(附源文件)
  • docker 02网络
  • Rollup vs Webpack 深度对比:前端构建工具终极指南
  • (二十六)深度解析领域特定语言(DSL)第四章——词法分析:基于正则表达式的词法分析器
  • 完全渲染后的页面内容
  • Matlab 实现基于深度学习的高压开关柜多故障实时检测方法研究
  • 《TCP/IP协议卷1》第1章 概述
  • Panthor 开源方案与 Mesa 图形库的技术解析
  • 【地图服务限制范围】
  • Odoo 18 库存中管理最低安全库存规则(再订货规则)
  • Python Day49 学习(日志Day19复习)
  • 【Java多线程从青铜到王者】阻塞队列(十)
  • 欧拉系统openEuler-24.03忘记密码,如何改密码
  • Python训练营-Day29-复习日
  • 修改FFMpeg的日志函数av_log,使其在记录日志时能显示调用该函数的位置(文件名和行号)
  • Metastore 架构示意图和常用 SQL
  • 前端加密当日
  • 力扣前缀和
  • 河南农担携手Gitee企业版:构建农业金融数字化研发新基建
  • 网络层协议:IP
  • qt初识--02
  • 移动电储能工作原理及SOC约束解析
  • 光谱相机叶绿素荧光成像技术的原理