目录
[一、stringstream 概述编辑](#一、stringstream 概述编辑)
[2.2 基于带初始字符串构造函数的拼接(覆盖式拼接)](#2.2 基于带初始字符串构造函数的拼接(覆盖式拼接))
[三. stringstream在LeetCode的常见用法](#三. stringstream在LeetCode的常见用法)
[四 .习题实践](#四 .习题实践)
[反转字符串中的单词 (重点)](#反转字符串中的单词 (重点))
🌼🌼前言:在 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
在上述代码中:
- 首先创建了一个空的
s
tringstream****对象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
函数会修改原始字符串,并且在多线程环境下可能会出现问题,而s
tringstream不会修改原始字符串,并且可以在更复杂的 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
。
浮点数类型转换:
对于将字符串转换为浮点数(如float
或double
) ,过程与整数转换类似。例如,将字符串"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"
**。
四 .习题实践
反转字符串中的单词 (重点)
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;
}
};
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++ 编程中处理字符串的得力工具。
松树千年终是朽,槿花一日自为荣😊☺