目录
🌼🌼前言:在 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
。
浮点数类型转换:
对于将字符串转换为浮点数(如float
或double
),过程与整数转换类似。例如,将字符串"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"
。
四 .习题实践
反转字符串中的单词 (重点)
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;
}
};
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++ 编程中处理字符串的得力工具。
松树千年终是朽,槿花一日自为荣😊☺