文章目录

  • 1、C风格字符串和C++字符串区别
  • 2、C++std::string类
    • 2.1、使用std::string类
    • 2.2、字符串比较
    • 2.3、字符串与数字相互转化
    • 2.4、字符串的截取操作
    • 2.5、字符串的查找
    • 2.6、寻找集合内的任意字符
    • 2.7、替换子字符串
  • 3、std::string_view
    • 3.1、string_view和string的运算符操作
    • 3.2、string_view的字符串收缩

1、C风格字符串和C++字符串区别

我们编写的每个应用程序都会使用某种类型的字符串,使用C语言时,没有太多选择,只能使用普通的以’\0’结尾的字符数组表示的字符串这种表达方式会导致许多问题,例如会导致安全漏洞的缓冲区溢出,C++标准库包含一个安全易用的std::string类,这个类符合RALL思想,没有这些缺点

2、C++std::string类

C++提供了一个得到极大改善的字符串概念,并作为标准库的一部分提供了这个字符串的实现。在C++中,std::string是一个类(实际上是basic_string模板类的一个实例),这个类支持< cstring >中提供的许多功能,还能自动管理内存分配

2.1、使用std::string类

C++的string类使用起来比C风格字符串更容易,以为它内部封装了许多运算符重载,如下是测试代码:

#include<iostream>
#include<string>int main()
{std::string str1 = "hello";std::string str2 = " world";auto str3 = str1 + str2;std::cout << str3 << std::endl;return 0;
}

2.2、字符串比较

在C++的string类中,操作符(==、!=、<、>等)都被重载了,这些运算符可以操作真正的字符串的字符,单独的字符可以通过方括号运算符[]访问。
C++string类另外提供了一个compare()方法,它的行为类似于C语言的strcmp()具有类似的返回类型,下面是测试代码:

#include<iostream>
#include<string>int main()
{std::string a = "12";std::string b = "34";auto ret = a.compare(b);if (ret < 0){std::cout << "a<b" << std::endl;}else if (ret > 0){std::cout << "a>b" << std::endl;}else if (ret == 0){std::cout << "a==b" << std::endl;}return 0;
}

测试代码的结果:

2.3、字符串与数字相互转化

很多情况下我们输出某条包含数字的语句时都需要将数字转化为字符串才可以将语句输出,如下是std标准库中封装的数字转化为字符串接口:

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

下面是std::to_string的接口的案例:

#include<iostream>
#include<string>int main()
{int num = 42;auto str = std::string("I have ") + std::to_string(42) + std::string("yuan");std::cout << str << std::endl;return 0;
}

上面讲了数字转化为字符串,如下是字符串转化为数字的接口:


接下来是字符串转化为数字的案例:

#include<iostream>
#include<string>int main()
{//字符串转化为整数std::string str1 = "42";auto num = std::stoi(str1);std::cout << num << std::endl;//字符串转化为浮点型std::string str2 = "3.14";auto dot = std::stof(str2);std::cout << str2 << std::endl;return 0;
}

注意:std::stoi/stof/stod/stoll等,它们的第二个参数是size_t类型的pos指的是非数字部分的位置,用于将非数字部分过滤掉,第三个参数是int 类型的base用于进行进制的转化,它默认是十进制

2.4、字符串的截取操作

std::string提供了一个截取字符串的接口,它会截取从pos位置开始,长度为len的子字符串,原字符串不会发生改变,它的原型如下:

string substr(size_t pos=0,size_t len=-1)const

如果原字符串剩余部分长度不足len,则返回长度小于len的子字符串而不会出错。如果pos超出原字符串的范围,则会抛出std::out_of_range的异常,如下是字符串截取的案例:

#include<iostream>
#include<string>int main()
{std::string str = "helloSakura";std::cout << "从第2个字符开始截取长度为4的字符串:" << str.substr(2, 4) << std::endl;std::cout << "从第2个字符开始截取长度为99的字符串:" << str.substr(2, 99) << std::endl;std::cout << "从第2个字符开始截取到末尾的字符串:" << str.substr(2) << std::endl;std::cout << "从头开始截取长度为5的字符串:" << str.substr(0, 5) << std::endl;//throw out_of_range//std::cout << "从第100个字符开始截取长度为5的字符串:" << str.substr(100, 5) << std::endl;return 0;
}

测试代码的运行结果:

2.5、字符串的查找

当我们要查找某一个字符串的子串时,可以通过string类中的find()方法查找,如下是find()方法的原型:

find(str,pos):如果找到了给定的子串,则返回它的位置;如果没有找到,则返回string::npos,如果给定了pos位置,则会从pos位置开始查找给定str,而不是从最开始位置查找str

如下是find()的寻找子字符的测试例子:

#include<iostream>
#include<string>int main()
{std::string str = "helloSakura";std::cout << "查找h字符的结果:" << str.find('h') << std::endl;std::cout << "查找e字符的结果:" << str.find('e') << std::endl;std::cout << "查找l字符的结果:" << str.find('l') << std::endl;std::cout << "查找o字符的结果:" << str.find('o') << std::endl;std::cout << "查找a字符的结果:" << str.find('a',2) << std::endl;return 0;
}

测试代码的结果:

如下是find()的应用案例:计算子字符串出现次数

#include<iostream>
#include<string>size_t stringCount(const std::string& str, const std::string& sub)
{size_t num=0, pos = 0;while (true){pos = str.find(sub, pos);if (pos == str.npos){break;}num++;pos += sub.size();}return num;
}int main()
{std::cout << stringCount("hellolldsdsallwds", "ll") << std::endl;return 0;
}

测试代码的结果:

2.6、寻找集合内的任意字符

find_first_of是string类中查找在字符串中第一个与指定字符串中的某个字符匹配的字符,返回它的位置。它的原型如下:

寻找字符串集合内的任意字符的测试代码:

#include<iostream>
#include<string>int main()
{std::string str = "helloSakura!!";auto it = str.find_first_of("lSa");std::cout << it << std::endl;return 0;
}

测试代码的结果:

2.7、替换子字符串

replace()是string类中用来替换一段子字符串的接口,它的原型为:

如下是replace()的代码测试:

#include<iostream>
#include<string>int main()
{std::string str = "make Sakura happy";str.replace(5, 6, "Naruto");std::cout << str << std::endl;return 0;
}

测试代码的结果:

下面使用replace()批量替换字符串案例:

#include<iostream>
#include<string>void replace_allStr(std::string& str, const std::string& from, const std::string& to)
{size_t pos = 0;while (true){pos = str.find(from, pos);if (pos == str.npos)break;str.replace(pos, from.size(), to);pos += from.size();}
}int main()
{std::string str = "hello Sakura,and good luck for Sakura!!";replace_allStr(str, "Sakura", "Naruto");std::cout << str << std::endl;return 0;
}

测试代码的结果:

3、std::string_view

在C++17之前,为接收只读字符串的函数选择形参类型一直是一件进退两难的事情。若使用std::string,则必须调用c_str()或则data()来获取const char*。更糟糕的是,函数将失去std::string良好的面向对象的方面和良好的API。

在C++17中,通过引入std::string_view类解决了所有问题,std::string_view类是std::basic_string_view类模板的实例化。string_view基本就是const string&的简单替代品,但不会产生开销。它不复制字符串,string_view支持与std::string类似的接口。一个例外是string_view缺少c_str()的接口,但data()可用。另外string_view添加了remove_prefix(size_t)和remove_suffix(size_t)方法,前者将起始指针前移给定的偏移量来收缩字符串,后者则是将结尾指针倒退给定的偏移量来收缩字符串

如下是string_view简单的使用案例:

#include<iostream>
#include<string>
#include<string_view>int main()
{std::string str1 = "hello";//深拷贝std::string str2 = str1;//弱引用std::string_view sv1 = str1;//浅拷贝std::string_view sv2 = sv1;//打印未修改的测试结果std::cout << "str1:" << str1 << std::endl;std::cout << "str2:" << str2 << std::endl;std::cout << "sv1:" << sv1 << std::endl;std::cout << "sv2:" << sv2 << std::endl;//分隔符std::cout << "-----------------------------------------" << std::endl;//修改str1的第一个字符str1[0] = 'H';//打印修改后的结果std::cout << "str1:" << str1 << std::endl;std::cout << "str2:" << str2 << std::endl;std::cout << "sv1:" << sv1 << std::endl;std::cout << "sv2:" << sv2 << std::endl;return 0;
}

测试代码的结果:

注意:str2是对str1的深拷贝,因为调用了std::string的拷贝构造函数,所以str1被修改时,str2仍然不变。sv1和sv2都是指向str1的弱引用,所以str1被修改时,sv1和sv2都被改变

3.1、string_view和string的运算符操作

当我们将string_view类型的常量弱引用类型的字符串和string类型的字符串进行相加(运算符+)操作时会出错,必须要先将string_view转化为const char*,也就是调用data()接口,测试代码如下:

#include<iostream>
#include<string>
#include<string_view>int main()
{std::string str1 = "hello";std::string_view sv1 = " world";//使用+号运算符时,必须将string_view转化为const char*auto it = str1 + sv1.data();//使用append追加字符串不会出错auto it2 = str1.append(sv1);std::cout << it2 << std::endl;return 0;
}

3.2、string_view的字符串收缩

之前讲到了string_view除了可以使用string中的接口以外,自身也添加了两个新的接口,remove_prefix()和remove_suffix(),这两个接口用于实现字符串的收缩,下面是简单的使用这两个接口的案例:

#include<iostream>
#include<string>
#include<string_view>int main()
{std::string str1 = "hello Sakura";std::string_view sv1 = str1;//从前向后收缩1个字符sv1.remove_prefix(1);std::cout << "sv1:" << sv1 << std::endl;//从后向前收缩一个字符sv1.remove_suffix(1);std::cout << "sv1:" << sv1 << std::endl;return 0;
}

测试代码的结果:

string和string_view用法指南相关推荐

  1. 【C++标准库】std::string用法指南源码剖析

    文章目录 1.ASCII码 (1)计算机如何表达字符 2.C 语言中的字符类型 char (1)思想:char 即整数 (3)C 语言帮手函数 (4)C语言中的字符串 (4)C 语言转义符 3.C++ ...

  2. string类具体用法

    string类具体用法 二话不说上代码 #include<string> #include<iostream> #include<algorithm> using ...

  3. string和stringstream用法总结

    string和stringstream用法总结 一.string string 是 C++ 提供的字串型態,和 C 的字串相比,除了有不限长度的优点外,还有其他许多方便的功能.要使用 string, ...

  4. string的常见用法详解

    目录 string的定义 string中内容的访问 string常用函数实例解析 在C语言中,一般使用字符数组char str[]来存放字符串,但是使用字符数组有时会显得操作麻烦,而且容易因经验不足而 ...

  5. 【转】SASS用法指南

    SASS用法指南 阮一峰的,偏sass用法教程 sass入门 偏实战的基础用法

  6. String.format() 方法用法解说

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. String chargeFlowUrl = _AGENT_URL+ "?agentAcc ...

  7. C++string类常用函数 c++中的string常用函数用法总结

    string类的构造函数: string(const char *s);    //用c字符串s初始化 string(int n,char c);     //用n个字符c初始化 此外,string类 ...

  8. curl 的用法指南

    curl 的用法指南 转自:http://www.ruanyifeng.com/blog/2019/09/curl-reference.html 作者: 阮一峰 日期: 2019年9月 5日 简介 c ...

  9. CSS: SASS用法指南 (附视频)

    观看视频:  CSS: SASS用法指南 学过CSS的人都知道,它不是一种编程语言. 你可以用它开发网页样式,但是没法用它编程.也就是说,CSS基本上是设计师的工具,不是程序员的工具.在程序员眼里,C ...

最新文章

  1. sscanf用法总结
  2. BootstrapTable
  3. 人工智能写散文之错位时空
  4. HNOI2015题解
  5. Python学习笔记:错误,测试,调试(承)
  6. 2015年第六届蓝桥杯C/C++ A组国赛 —— 第五题:切开字符串
  7. asp.net 六大对象之Request、Response
  8. “” '' ``区别 初学者自用
  9. Pantera Capital合伙人:ETH已成为机构资产类别
  10. Xamarin.Form 超链接 用手势实现
  11. RTOS osDelay和taskDelay关系
  12. 软件公司所犯的3种最严重的营销错误,你应该来看看
  13. Modbus PLC攻击分析:从Modbus Poll/Slave到M340
  14. php构造函数里抛出异常_构造函数、析构函数抛出异常的问题
  15. oracle日期如何比较,Oracle日期比较
  16. CC2530 ZIGBEE ZStack 学习笔记——OSAL部分(学习《都教授讲Zigbee》视频时所作的笔记)
  17. codeup 1006
  18. 【STM32】BootLoader介绍、编写 以及 OTA常见方案分析(差分升级 全量升级 AB面升级)
  19. jsp190ssm健身俱乐部会员管理系统
  20. 项目启动报错 Error running ‘xxxApplication‘;Command line is too long,Shoerten command line for........

热门文章

  1. latex中公式的上下限和左右如何改变,即独立公式和行间公式的切换
  2. 推荐10个Vue 3.0开发的开源前端项目
  3. PacketTracer Physical view wireless single problem
  4. OpenCV的cv::cvtColor()
  5. mysql动态变量_Mysql的变量一览
  6. css如何去掉或修改浏览器默认滚动条
  7. Hive视图与物化视图
  8. linux socket函数详解,linuxSocket_函数.doc
  9. Tails OS 让你实现隐形上网!
  10. mysql触发器优缺点_MySQL 的触发器