功能强大的stringstream类

目录

[一、stringstream 概述​编辑](#一、stringstream 概述编辑)

二、stringstream的创建

1.构造函数的细节

2.字符串拼接覆盖功能

2.1.基于默认构造函数的拼接

[2.2 基于带初始字符串构造函数的拼接(覆盖式拼接)](#2.2 基于带初始字符串构造函数的拼接(覆盖式拼接))

[三. stringstream在LeetCode的常见用法](#三. stringstream在LeetCode的常见用法)

1.默认空格分割:便捷的基础用法

2.类型转换

从字符串到基本数据类型的转换

从基本数据类型到字符串的转换

[四 .习题实践](#四 .习题实践)

[反转字符串中的单词 (重点)](#反转字符串中的单词 (重点))

总结:(看到这里,很了不起🚀🚀)


🌼🌼前言:在 C++ 的编程世界里,**stringstream是一个极为重要且实用的工具,它为字符串处理提供了强大的功能。然而,在使用stringstream**时,有诸多细节需要我们仔细留意,才能充分发挥其优势并避免潜在的错误。

一、stringstream 概述

**stringstream是 C++ 标准库<sstream>**中的一个类,它允许我们像操作流一样操作字符串。这意味着我们可以方便地进行字符串与其他数据类型之间的转换、字符串的拼接、分割等一系列操作,极大地提高了字符串处理的灵活性和效率。

使用时需要包含头文件**#include<sstream>**

二、stringstream的创建

1.构造函数的细节

**stringstream**拥有多种构造函数,其中两个较为常用的构造函数有着明显的区别:

无参构造函数:

1. 创建一个对象,向对象输入字符串:

cpp 复制代码
    // 创建一个 string类  对象 s
	string s("hello stringstream");
	// 创建一个 stringstraeam类 对象 ss
	stringstream ss;
 
	// 向对象输入字符串 : "<<" 表示向一个对象中输入
	ss << s;
	cout << ss.str() << endl;

输出如下:

需要注意的是:stringstream类没有 重载 (operator<<),这一点与string类不同**,string类可以直接通过cout<< string ("1234")<<endl;输出** 。stringstream则是通过**str()**函数,该函数返回了一个字符串,进行输出。

2. 在创建对象的时候使用字符串初始化:

cpp 复制代码
    // 创建一个 stringstraeam类 对象 ss
	stringstream ss("hello stringstream");
 
	cout << ss.str() << endl;

2.字符串拼接覆盖功能

2.1.基于默认构造函数的拼接

当使用默认构造函数创建**stringstream**对象,如s**tringstream ss;时,后续通过多次使用<<**操作符输入字符串,这些字符串会依次拼接在一起。

例如:

cpp 复制代码
#include <iostream>
#include <sstream>

int main() {
    stringstream ss;
    ss << "Hello";
    ss << " ";
    ss << "World";

    std::cout << ss.str() << std::endl;

    return 0;
}
//输出Hello world

在上述代码中:

  • 首先创建了一个空的stringstream****对象ss
  • 然后通过**连续的<<操作符,依次将字符串"Hello"" "(空格)和"World"**输入到ss中。
  • 最后调用**ss.str()** 获取拼接好的完整字符串,并通过cout输出,输出结果为**Hello World。**

这种方式适用于在程序运行过程中,根据不同的逻辑逐步拼接生成一个完整的字符串的场景。

2.2 基于带初始字符串构造函数的拼接(覆盖式拼接)

若使用带初始字符串的构造函数创建**stringstream象,如stringstream ss("Initial String");,后续再使用<<**操作符输入新字符串时,新字符串会从起始位置开始覆盖原有字符串的内容,直到新字符串输入完毕。

cpp 复制代码
#include <iostream>
#include <sstream>

int main() {
    stringstream ss("Bas xuwen ");
    ss << "New ";
    std::cout << ss.str() << std::endl;
    ss<<"hello world"
    std::cout << ss.str() << std::endl;

    return 0;
}

如果想要在这种构造方式下实现类似追加的拼接效果,可以先将原字符串保存起来,再结合**<<**操作符进行拼接操作。比如:

cpp 复制代码
#include <iostream>
#include <sstream>

int main() {
    stringstream ss("Base");
    string original = ss.str();
    ss.str("");  // 清空当前内容

    ss << original;
    ss << " New";

    std::cout << ss.str() << std::endl;

    return 0;
}

在上述修改后的代码中:

  • 先创建了初始化为"Base"的stringstream对象ss,并将其初始字符串保存到original变量中。
  • 然后通过ss.str("");清空ss的当前内容,以便后续重新拼接。
  • 接着先将保存的原字符串original重新输入到ss中,再通过<<操作符输入新字符串" New",这样就实现了类似追加的拼接效果,最终输出结果为Base New

三. stringstream在LeetCode的常见用法

1.默认空格分割:便捷的基础用法

原理:stringstream 在默认情况下,会以空格作为分隔符来分割字符串。这是因为**stringstream的设计目的之一是方便地处理文本流,而在很多文本处理场景中,单词之间是以空格来分隔的 。当使用>>操作符从stringstream**中提取数据时,它会自动跳过空格,直到遇到下一个非空格字符,然后开始读取字符,直到再次遇到空格或者到达字符串末尾。

简单来说:stringstream 可以通过重载operator>>将自己的数据从左到右输出输出的数据自己将不在拥(这可不是拷贝) (像money一样越花,钱越少😀😀)。空格作为标识符代表这一次输出结束。

cpp 复制代码
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    std::string input = "Hello world how are you";
    std::stringstream ss(input);
    std::string word;
    while (ss >> word)
    {
        std::cout << word << std::endl;
    }
    return 0;
}
cpp 复制代码
Hello
world
how
are
you

与其他分割方式对比

与手动分割字符串相比,**stringstream的空格分割功能更加方便。例如,如果要手动实现空格分割,可能需要编写复杂的循环来遍历字符串,判断每个字符是否为空格,然后提取单词。而stringstream**则简化了这个过程。

string使用strtok 函数(C 风格的字符串分割函数)相比,stringstream是面向对象的 C++ 方式,更符合 C++ 的编程风格。strtok函数会修改原始字符串,并且在多线程环境下可能会出现问题,而stringstream不会修改原始字符串,并且可以在更复杂的 C++ 程序中方便地与其他流操作结合使用。

2.类型转换

从字符串到基本数据类型的转换

整数类型转换

stringstream可以方便地将字符串转换为整数类型。例如,将一个表示数字的字符串转换为int类型。假设我们有一个字符串"123",可以使用**stringstream**进行转换

cpp 复制代码
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    std::string numStr = "123";
    int num;
    std::stringstream ss(numStr);
    ss >> num;
    std::cout << "转换后的整数为: " << num << std::endl;
    return 0;
}
  • 在这个示例中,首先创建了一个包含数字字符串**"123"string对象numStr** 。然后创建了stringstream对象ss并使用numStr进行初始化。接着使用**ss >> num**操作,stringstream会尝试从字符串中提取整数并存储到num变量中。最后输出转换后的整数123

浮点数类型转换

对于将字符串转换为浮点数(floatdouble ,过程与整数转换类似。例如,将字符串"3.14"转换**为double**类型

cpp 复制代码
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    std::string floatStr = "3.14";
    double num;
    std::stringstream ss(floatStr);
    ss >> num;
    std::cout << "转换后的浮点数为: " << num << std::endl;
    return 0;
}
  • 这里同样先创建字符串,然后通过**stringstream提取浮点数到num变量中,输出结果为3.14**。
  • 注意事项
    • 当进行字符串到数字类型的转换时,如果字符串格式不符合数字类型的要求,转换将会失败。例如,如果尝试将"abc"转换为整数,stringstream会进入错误状态,转换后的变量值将是不确定的。可以通过检查stringstream的状态来判断转换是否成功。例如,if(ss.good())表示转换成功,if(ss.fail())表示转换失败。
从基本数据类型到字符串的转换
  • 整数转换为字符串
  • 可以将整数等基本数据类型转换为字符串。例如,将整数**42**转换为字符串:
cpp 复制代码
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    int num = 42;
    std::stringstream ss;
    ss << num;
    std::string numStr = ss.str();
    std::cout << "转换后的字符串为: " << numStr << std::endl;
    return 0;
}

在这个示例中,首先创建了整数变量**num并赋值为42** 。然后创建**stringstream对象ss** ,通过**ss << num** 将整数**num输入到stringstream** 中。最后使用**ss.str()** 获取转换后的字符串并存储到numStr变量中,输出结果为**"42"**。

四 .习题实践

反转字符串中的单词 (重点)

151. 反转字符串中的单词 - 力扣(LeetCode)

cpp 复制代码
class Solution {
public:
    string reverseWords(string s) 
    {
         string res,temp;
         stringstream ss(s);
         while(ss>>temp)
         {
            res = temp + " " + res;
         }
         if(!res.empty())
         {
            res.pop_back();
         }
         return res;
    }
};

2. 两句话中的不常见单词

cpp 复制代码
class Solution {
public:
    vector<string> uncommonFromSentences(string s1, string s2) {
        
        stringstream ss;
        ss<<s1<<' '<<s2;

        string s;
        unordered_map<string,int> mp;
        while(ss>>s)
        {
          mp[s]++;
          s="";
        }

        vector<string> v;
        for(auto& ch:mp)
        {
            if(ch.second==1)
            {
                v.push_back(ch.first);
            }
        }
        return v;
    }
};
总结:(看到这里,很了不起🚀🚀)

**stringstream**在 C++ 字符串处理中功能强大且灵活,无论是字符串拼接、分割还是类型转换,都能在不同场景下发挥重要作用,帮助开发者高效处理字符串相关任务,尤其是涉及复杂数据处理和转换的情况,是 C++ 编程中处理字符串的得力工具。
松树千年终是朽,槿花一日自为荣😊☺

相关推荐
__lost2 分钟前
Rust语言俄罗斯方块(漂亮的界面案例+详细的代码解说+完美运行)
开发语言·算法·rust
Romanticroom6 分钟前
简单图论农场派对
算法
bbppooi35 分钟前
排序学习整理(1)
c语言·数据结构·学习·算法·排序算法
Yanbin_Q42 分钟前
C 语言静态库与动态库的生成和使用
c++
h0l10w1 小时前
LeetCode【代码随想录】刷题(数组篇)
c++
是糖不是唐1 小时前
代码随想录算法训练营第五十五天|Day55 图论
c语言·数据结构·算法·图论
爱穿西装的C先生1 小时前
C++学习日记---第13天(类和对象---封装)
c++·学习·程序人生·蓝桥杯
AKA 埼玉1 小时前
第一周周总结
c++
legend_jz1 小时前
【linux】手搓线程池
linux·运维·服务器·c++·笔记·学习·学习方法
seabirdssss2 小时前
力扣_876. 链表的中间结点
java·数据结构·算法·leetcode·链表