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

C++| STL之string

前言:最近在做LeetCode算法题,C++字符串通常都是string作为输入,所以补充一下STL里面string。在介绍的具体使用的时候,会补充char字符串相关的进行对比。

string

  • 创建
  • 大小和容量
  • 遍历
  • 字符串比较
  • 插入字符
  • 拼接字符串
  • 分配内存
  • 查找
  • 截取
  • 分割
  • string互转char*

创建

string s1;
string s2 (3,'a');// aaa
string s3 ("value");// value
string s4 (s3);// value
string s5 = "hello!";// hello!

大小和容量

string特有的函数

  • size()和length():返回string对象的字符个数,他们执行效果相同。
  • max_size():返回string对象最多包含的字符数,超出会抛出length_error异常。
  • capacity():重新分配内存之前,string对象能包含的最大字符数。

注意:max_size()是当前分配可容纳字符数,size()是已经使用的,例如下面代码。

string s = "abc"; 
s.reserve(20); 
cout << s.size() << endl;  // 3
cout << s.max_size() << endl;  // 31因为string内存分配按照(n*16-1)分配,能满足20大小的n=2

通用的函数

  • sizeof():返回占用内存的多少。返回的是数组在内存中占用的字节数,字符串数组会包含结束符。
  • strlen():只能用char* 做参数,而且必须以’\0’结尾的,但不计算后面的’\0’。对比,sizeof是运算符,strlen是函数。

效果对比

string s = "abcd";
cout << sizeof(s) << endl;  //16,string每个字符占内存大小和char不同
cout << sizeof("abcd") << endl;  //5 
cout << s.length() << endl; //4
cout << s.size() << endl; //4,s.length()和s.size()功能一样
cout << strlen("abcd") << endl; //4,不计算后面的’\0’

常用:size()、length()、sizeof()。

遍历

string和vector比较相似,都是不定长,vector的操作基本都可以用于string,所以也能像vector那样遍历string里面的字符。

string s = "hello!";// hello!
for(int i=0;i<s.size();i++)cout<<s[i]<<endl

字符串比较

  1. 关系运算符
string s1("abcd");
string s2("abcd");
if(str1 == str2)cout<<"str1 = str2"<<endl;
  1. compare函数
// 比较的字典序,每个字符逐个对比,越小越靠前,例如abc比abd小,hello比hellow小,因为hello比完了hellow还有个w
string s1="hello";
string s2="hellow";int a=s1.compare(s2);// s1等于s2返回0,s1小于s2返回-1,s1大于s2返回1
cout<<a<<endl;// -1int b=s1.compare(2,3,s2);// s1下标为2的字符开始的3个字符llo和s2进行比较
cout<<b<<endl;// 1int c=s1.compare(2,3,s2,1,3);// s1下标为2的字符开始的3个字符llo和s2下标为1的字符开始的3个字符ell比较
cout<<c<<endl;// 1
  1. 遍历:全部遍历按照自己的规则一一对比,前面提过遍历了。

插入字符

函数:

  • push_back(char):尾插一个字符char。
  • insert(pos,char):在制定的位置pos前插入字符char。

测试代码:

string s;
// 尾插一个字符
s.push_back('a');
s.push_back('b');
s.push_back('c');
cout<<"s:"<<s<<endl; // s:abc// 指定位置插入
s.insert(s.begin(),'a');
cout<<"s insert:"<<s1<<endl; // s insert:aabc

拼接字符串

方法:

  • 运算符:str+=str1。
  • append(str)

测试代码:

string s="hello";
string s1=" world";
s.append(s1);// hello world
// s+=s1;// 可替换

分配内存

函数:

  • reserve():为容器预留足够的空间,避免不必要的重复分配,减少系统开销,影响capacity。
  • resize():调整容器中有效数据区域的尺寸,如果尺寸变小,多余的截掉;若尺寸变大,第二个参数填充,影响size。

疑问:看到这两个概念的时候,会想resize有点用,可以截断string,但是reserve似乎没必要。因为string不是不定长吗,看可以不断push_back,不需要预先分配足够的空间啊。
解答:这个和string的运行机制有关,实际上每个string声明和使用的时候都会预先分配好一个容量capacity,如果不定长添加给string后总容量超过了capacity,系统会重新malloc一块连续长度足够的内存,然后把数据都复制到新的位置,再把原先的内存还给系统。如果能预先知道需要多少空间,可以提前reserve,这样能够避免系统开销,提高运行效率。

查找

查找函数find:

  • str.find(str1,pos):在str字符串中找到str1子串的首位置pos,找不到内容则字符串搜索函数返回npos.

截取

截取函数substr:

  • str.substr(pos,count):截取str字符串pos位置开始,count长度的子串。

分割

stirng:并没有通用的函数,得自己根据其它功能的函数实现。

  • string流:用string流中的getline函数,关于stream流相关的内容,我在博客C++| excel存取开头有介绍。
  • find和substr函数组合:每次find到分隔符位置,就截取一部分。

string流代码实现string分割:

string str= "hello world";
istringstream iss(str);	// 输入流
string token;			// 接收缓冲区
char split=' ';
while (getline(iss, token, split))	// 以split为分隔符
{cout << token << endl; // 输出
}
// 结果:
// hello
// world

find和substr函数实现string分割:

string str= "hello world";
char split=' ';
str+=split;// 末尾也加入分隔符
size_t pos=str.find(split);// size_t表示C中任何对象所能达到的最大长度,无符号整数
while(pos!=str.npos)// 找不到内容则字符串搜索函数返回npos
{string temp = str.substr(0, pos);cout << temp << endl; // 输出str=str.substr(pos + 1, str.size());pos = str.find(split);
}
// 结果:
// hello
// world

char:

  • strtok(sign):sign指定分割符,根据sign来分割字符串。
char str[] = "hello world!";
const char *split = " !";// 空格和感叹号
char *p = strtok(str,split);
while( p2 != NULL )
{cout<<p<<endl;p = strtok(NULL,split);
}
// 结果
// hello
// world

对比起来,似乎char的方法方便多了,可以string转char,下一部分会详细介绍。

注意:分割符如果是转义字符得转移符号“\”。

string互转char*

string转char*:

  • c_str():返回一个以’\0’结尾的字符数组。
  • data():仅返回字符串内容,而不含有结束符’\0’。
  • 遍历一个个位置赋值。
char ch1[20],ch2[20];
string s="123456";
strcpy(ch1,s.c_str());
strcpy(ch2,s.data());

char*转string:直接赋值。

string s;
char* p ="hello";
s = p;
http://www.lryc.cn/news/389164.html

相关文章:

  • [数据集][目标检测]游泳者溺水检测数据集VOC+YOLO格式4599张2类别
  • JAVA实现麦克风说话同声传译
  • LabVIEW与PLC通讯方式及比较
  • 2024/6/30 英语每日一段
  • Postman接口测试工具的原理及应用详解(五)
  • 208.贪心算法:买卖股票的最佳时机||(力扣)
  • 【论文阅读】伸缩密度比估计:Telescoping Density-Ratio Estimation
  • MongoDB数据库 MQL (MongoDB Query Language)语句大全
  • Java代码基础算法练习-计算平均身高-2024.07.02
  • BIOS设置与系统分区
  • linux的安装程序 与 文件 相关的命令
  • SAP_ABAP相关日语单词
  • Python中的除法操作详解
  • 第1章 人工智能的基础概念与应用导论
  • jenkins api部署时,一直提示pending-Finished waiting
  • AI在创造还是毁掉音乐之论文
  • C++ STL容器:序列式容器-数组string,vector,array,bitset
  • ElementUI样式优化:el-input修改样式、el-table 修改表头样式、斑马格样式、修改滚动条样式、
  • 大数据面试题之Spark(6)
  • SpringSecurity中文文档(Servlet Anonymous Authentication)
  • 【Spring Boot 事务管理】
  • 【C++】C++指针在线程中调用与受保护内存空间读取方法
  • 安全隔离上网的有效途径:沙箱
  • jenkins下后台运行链接Jenkins服务脚本方法
  • 宠物空气净化器哪个品牌性价比高?宠物空气净器Top3品牌推荐
  • 苏州大厂面试题JAVA 面试集
  • 数据库取出来的日期格式是数组格式,序列化日期格式
  • 【Android】创建一个可以在屏幕上拖动的悬浮窗
  • SPI NAND、SD NAND和eMMC对比—MK米客方德
  • “深入解析:YUM仓库、RPM包与源码编译——Linux软件安装方式全面对比“