首页 > 编程语言 >`std::string_view`(c++17) 和 `std::stringstream` 使用区别·

`std::string_view`(c++17) 和 `std::stringstream` 使用区别·

时间:2024-09-23 15:24:28浏览次数:7  
标签:std string 17 stringstream 字符串 数据 view

std::string_viewstd::stringstream 都是 C++ 中处理字符串的工具,但它们的设计目标和使用场景非常不同。我们可以通过几方面进行对比。

1. 设计目的和核心功能

  • std::string_view:
    • 设计用于只读访问字符串或字符序列。
    • 是一个轻量级的字符串视图,不会持有字符串的数据,仅仅是对现有字符串的引用。
    • 适合高效地操作已有字符串或进行快速读取(例如子串操作、比较等),没有额外的内存分配。
      std::string_view 是 C++17 引入的一种轻量级的字符串视图类型,它提供了一种非常高效的方式来引用和操作现有的字符串(或字符数组)而不需要复制数据。

什么是 std::string_view

std::string_view 本质上是一个不可变的字符串引用,它可以指向现有的字符串数据(例如 std::string、C 风格的字符串数组等),而不实际拥有这些数据。
它的作用是让你能够高效地查看或操作某个字符串的子集,而不必进行额外的内存分配或数据拷贝。

为什么使用 std::string_view

  1. 避免不必要的拷贝: 传统的 std::string 在传递和处理时通常会复制数据,而 std::string_view 仅仅是一个对已有字符串的引用,避免了数据的复制和重新分配,提高了性能。
  2. 适用于只读操作: 如果你只需要读取字符串的内容而不需要修改,std::string_view 是一个很好的选择。
  3. 兼容性: std::string_view 可以直接从 std::string 或 C 风格字符串创建,并且使用起来十分灵活。
  4. 子串操作效率高: 使用 std::string_view 可以轻松地处理字符串的子串而不引起额外的内存分配。

std::string_view 的基本用法

#include <iostream>
#include <string>
#include <string_view>

int main() {
    // 从 C 风格字符串创建 string_view
    const char* cstr = "Hello, World!";
    std::string_view sv1(cstr);

    // 从 std::string 创建 string_view
    std::string str = "Hello, C++!";
    std::string_view sv2(str);

    // 输出 string_view 的内容
    std::cout << "String view 1: " << sv1 << std::endl;
    std::cout << "String view 2: " << sv2 << std::endl;

    // 获取子串 (不分配新内存)
    std::string_view sv3 = sv2.substr(0, 5); // "Hello"
    std::cout << "Substring view: " << sv3 << std::endl;

    // 遍历 string_view
    for (char ch : sv3) {
        std::cout << ch << ' ';
    }
    std::cout << std::endl;

    return 0;
}

常用操作

  • 构造:

    std::string_view sv1("Hello");  // 从 C 字符串构造
    std::string_view sv2(str);      // 从 std::string 构造
    
  • 子串操作:

    std::string_view sv = "Hello, C++!";
    std::string_view sub_sv = sv.substr(0, 5);  // 获取 "Hello"
    
  • 长度:

    std::size_t len = sv.length();  // 获取字符串的长度
    
  • 访问元素:

    char first_char = sv[0];  // 访问第一个字符
    
  • 比较:

    if (sv == "Hello") {
        // 相等
    }
    

注意事项

  1. 寿命管理: std::string_view 不拥有其指向的数据,因此必须确保它指向的字符串在 std::string_view 使用期间有效。否则会导致悬空引用的问题。
  2. 不可修改: std::string_view 是只读的,不能修改它指向的字符串内容。如果需要修改,应该使用 std::string 或其他可变的字符串类型。
  • std::stringstream:
    • 设计用于字符串的读写操作,类似于内存中的字符流(和 std::cinstd::cout 类似)。
    • 持有字符串数据,能够进行字符串的格式化操作(如插入、提取等)。
    • 适合动态生成或修改字符串的场景,比如构建一个复杂的字符串或从字符串中提取特定类型的数据。

2. 性能比较

  • std::string_view:

    • 高效:不进行内存拷贝或数据持有,操作时间复杂度通常为常数时间。
    • 适用于只读访问已有字符串,非常适合处理子串或无需修改的字符串。
    • 缺点:只能对已有的字符串或字符数组操作,不能修改数据或进行复杂的字符串拼接等操作。
  • std::stringstream:

    • 灵活:可以动态构建、修改和操作字符串。
    • 相对较慢:由于 std::stringstream 需要动态分配内存并持有数据,在处理大量数据时会有性能开销。
    • 缺点:不适合只读访问已有的字符串。它的设计目标是进行读写和格式化操作。

3. 使用场景

  • std::string_view 适合的场景:

    • 高效读取已有字符串(比如处理输入字符串的子串)。
    • 解析静态字符串或从已有的数据块中获取特定内容。
    • 只需要读取,而不需要修改字符串的地方,尤其是在性能敏感的场合。
    std::string_view sv("Hello, World!");
    if (sv.substr(0, 5) == "Hello") {
        std::cout << "Substring match!" << std::endl;
    }
    
  • std::stringstream 适合的场景:

    • 需要对字符串进行格式化、拼接、插入、修改等操作。
    • 需要将数据从其他类型(如 intdouble 等)转换为字符串,或从字符串中提取数据。
    std::stringstream ss;
    ss << "Number: " << 42 << ", Float: " << 3.14;
    std::string result = ss.str();  // "Number: 42, Float: 3.14"
    

4. 数据所有权和内存管理

  • std::string_view:

    • 不拥有字符串的所有权,只是对现有字符串的引用。用户需要确保引用的字符串在 string_view 的生命周期内有效。
    • 由于它不拷贝数据,内存管理效率很高。
  • std::stringstream:

    • 持有字符串数据,意味着它会管理数据的内存分配和释放。在进行复杂的字符串拼接和操作时,可能会引起多次内存分配和拷贝。

5. 字符串修改

  • std::string_view:

    • 不允许修改字符串,因为它是一个只读视图。只能访问而不能更改内容。
  • std::stringstream:

    • 允许修改字符串,可以向流中添加、删除或提取数据。

6. 代码对比

  • std::string_view 例子(只读访问):

    std::string str = "Hello, World!";
    std::string_view sv(str);
    std::cout << sv.substr(7, 5);  // 输出: "World"
    
  • std::stringstream 例子(读写操作):

    std::stringstream ss;
    ss << "Hello, " << "World!";
    std::string result = ss.str();  // result 是 "Hello, World!"
    

7. 总结

  • std::string_view 是高效处理只读字符串的工具,适用于不需要修改数据的场合,主要用于提高性能。
  • std::stringstream 则是用于处理字符串的动态操作,如格式化、拼接、转换等,适合需要读写字符串的场景。

根据实际需求选择合适的工具。如果你只需要高效读取字符串内容而不修改,std::string_view 更合适;如果你需要操作或构造字符串,std::stringstream 则是更好的选择。

标签:std,string,17,stringstream,字符串,数据,view
From: https://www.cnblogs.com/niumachen/p/18427126

相关文章

  • C++ string
    在C++中,std::string类是处理字符串的主要工具。它提供了丰富的功能和方法来简化字符串操作,使得开发者可以更加方便地进行文本数据的处理。构造函数std::string类有多种构造函数供用户选择:使用C风格字符串初始化:string(constchar*s);使用指定字符重复初始化:string(size_......
  • 框架漏洞(5-rce s2-057 CVE-2017-8046 CVE-2018-1273 Shiro-550)
    5-rce步骤一:环境部署cdvulhub/thinkphp/5-rcedocker-composeup-d步骤二:输入系统命令: whoami/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami步骤三:写入webshell到1.php/index.php?s=index/think\ap......
  • MIL-STD-1553B 在现代航空航天与军事领域的应用案例
    MIL-STD-1553B作为一种成熟且可靠的航空电子数据总线标准,在航空航天、军事等领域发挥着至关重要的作用。以下将通过几个具体的案例来展示其广泛的应用和卓越的性能。一、军用飞机航空电子系统 在先进的军用战斗机中,MIL-STD-1553B总线被广泛用于整合和管理各种航空电子设备,如飞......
  • <<编码>> 第 17 章 自动操作(1)--计算设备 示例电路
    info::操作说明首先闭合清零(clear)开关,清除8位触发器(锁存器)中的内容,并把16位计数器的输出置为0000H然后闭合RAM控制面板的控制端开关(接管信号开关)手动输入一组要加的数注:RAM地址0,1,2,3处已预设了1,2,3,4四个值断开接管控制开......
  • std::vector 和 std::map 都支持以下比较运算符
    在C++标准库中,std::vector和std::map都支持以下比较运算符:==(相等运算符)!=(不等运算符)<(小于运算符)<=(小于等于运算符)>(大于运算符)>=(大于等于运算符)1.std::vector的比较对于std::vector,这些运算符通过词典序比较(lexicographicalcomparison)进行。词典序比较类似于字......
  • 设计原理图:417-基于XCVU9P+ C6678的8T8R的无线MIMO平台
    基于XCVU9P+C6678的8T8R的无线MIMO平台一、板卡概述     北京太速科技板卡基于TI TMS320C6678DSP和XCVU9P高性能FPGA,FPGA接入4片AD9361无线射频,构建8输入8输出的无线MIMO平台,丰富的FPGA资源和8核DSP为算法验证和信号处理提供强大能力。二、技术指标 ● 板卡为......
  • 为何有时出现:Allowed memory size of 134217728 bytes exhausted (tried to allocate
    出现“Allowedmemorysizeof134217728bytesexhausted(triedtoallocate20480bytes)”这样的错误,意味着PHP脚本运行时消耗的内存超过了PHP配置允许的最大内存限制。这个错误通常是因为PHP脚本处理的数据量过大、内存消耗较高的任务或配置不当引起的。以下是几种解决......
  • 免费分享源码 SSM酒店信息管理系统 计算机毕业设计论文41731
    摘 要酒店信息管理系统是一种基于计算机技术的管理工具,旨在提高酒店业务效率和服务质量。该系统通过集成多个功能模块,实现酒店各项业务的自动化管理,包括客房信息管理、预订信息管理、入住信息管理、退房信息管理、续费信息管理等。该系统可以大大提高酒店管理的效率,减少......
  • 为何我安装完提示这个报错?:Array and string offset access syntax with curly braces
    错误信息 Arrayandstringoffsetaccesssyntaxwithcurlybracesisdeprecated 表明你在使用的PHP版本较高,而你的程序代码中使用了一些在较新版本中已弃用的语法。具体来说,这是PHP7.4及以上版本对数组和字符串偏移量访问语法 {} 的弃用警告。解决方案1.降低PHP......
  • 【C++驾轻就熟】string类以及string类的模拟实现
    目录一、为什么学习string类?二、标准库中的string类 2.1string类(了解)2.2string类的常用接口说明 1.string类对象的常见构造 2.string类对象的容量操作3.string类对象的访问及遍历操作 4.string类对象的修改操作5.string类非成员函数 三、 string类的......