功能强大的stringstream类

发布于:2024-11-28 ⋅ 阅读:(9) ⋅ 点赞:(0)

 

目录

 一、stringstream 概述​编辑

 二、stringstream的创建

1.构造函数的细节

 2.字符串拼接覆盖功能

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

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

 三. stringstream在LeetCode的常见用法

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

2.类型转换

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

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

 四 .习题实践

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

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


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

 一、stringstream 概述

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

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

 二、stringstream的创建

1.构造函数的细节

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

无参构造函数:

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

    // 创建一个 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. 在创建对象的时候使用字符串初始化:

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

 2.字符串拼接覆盖功能

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

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

例如:

#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");,后续再使用<<操作符输入新字符串时,新字符串会从起始位置开始覆盖原有字符串的内容,直到新字符串输入完毕。

#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;
}

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

#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一样越花,钱越少😀😀)。空格作为标识符代表这一次输出结束。

 

#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;
}
Hello
world
how
are
you

与其他分割方式对比

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

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

2.类型转换

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

整数类型转换

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

#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类型

#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转换为字符串:
#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)

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. 两句话中的不常见单词

 

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++ 编程中处理字符串的得力工具。 

 松树千年终是朽,槿花一日自为荣😊☺