梳理下istringstream ostringstream stringstream的关系
今天在练习面试题37. 序列化二叉树的时候,需要用到istringstream
,ostringstream
这两个类,不太熟悉,查找相关文档,记录下来。
在头文件<sstream>中定义了三个字符串流,分别是:
- istringstream:输入字符串流,是一个类
- ostringstream:输出字符串流,是一个类
- stringstream:输入/输出字符串流,是一个类
他们的继承关系如下图所示:
istringstream,此类的对象有一个字符串缓冲区,字符串缓冲区包含了一个字符序列。 可以使用成员方法str直接访问此字符序列,得到字符串对象string。重载的是右移运算符>>,提取格式化的输入,每次向运算符>>左边的变量输入一个单词,以空格为分隔符。
std::istringstream::str
string str() const;
void str (const string& s);
例子:
// istringstream::str
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::istringstream
int main () {
std::istringstream iss;
std::string strvalues = "32 240 2 1450";
iss.str (strvalues); // 将字符串strvalues复制到iss流中
for (int n=0; n<4; n++)
{
int val;
iss >> val; // 每次输出一个数字,空格为分隔符
std::cout << val << '\n';
}
std::cout << "Finished writing the numbers in: ";
std::cout << iss.str() << '\n'; // 通过str方法获取iss中的字符串
return 0;
}
编译和运行结果:
$ g++ 05_istringstream.cpp -o 05_istringstream.o
$ ./05_istringstream.o
32
240
2
1450
Finished writing the numbers in: 32 240 2 1450
ostringstream,此类的对象也有一个字符串缓冲区,字符串缓冲区包含了一个字符序列。 可以使用成员方法str直接访问此字符序列,得到字符串对象string。但是重载的是左移运算符<<,插入格式化的输出,将运算符<<左边的变量输入到ostringstream对象中。
std::ostringstream::str
string str() const;
void str (const string& s);
例子:
// ostringstream
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::ostringstream
int main () {
std::ostringstream oss;
oss << "string " << 100 << ' ' << 3.14; // 向oss对象输入string,int,char,float类型的数据
std::string s = oss.str(); // 获取oss对象中的字符串
std::cout << s << '\n';
return 0;
}
编译和运行结果:
$ vim 06_ostringstream.cpp
$ g++ 06_ostringstream.cpp -o 06_ostringstream.o -std=c++11
$ ./06_ostringstream.o
string 100 3.14
stringstream,将字符串对象与流相关联,使您可以像对待流一样读取字符串(如cin)。 可以使用成员方法str直接访问此字符序列,得到字符串对象string。这个类将右移运算符和**左移运算符<<**都进行了重载。
基本的方法如下:
clear() — 清除流中的数据
str() — 获得或设置流中字符串的内容,这是一个重载函数,有两个不同的调用方法
operator << — 向stringstream对象添加一个字符串
operator >> —从stringstream对象读取一些内容*
std::stringstream::str中str()方法:
string str() const;
void str (const string& s);
stringstream的例子:统计一个字符串中的单词数量,并打印每个单词的频率
输入:geeks for geeks geeks contribution placements
输出:
Number of words are: 6
contribution -> 1
for -> 1
geeks -> 3
placements -> 1
// using stringstream.
#include <iostream>
#include <sstream>
#include <string>
#include <map>
using namespace std;
// 统计单词数量
int countWords(string str)
{
stringstream s(str); // 以空格为分隔符,分割每个单词
string word; // 存储单个的单词
int count = 0;
while (s >> word)
count++;
return count;
}
// 统计每个单词的词频
void printFrequency(string st)
{
map<string, int> FW; // map保存每个单词的词频
stringstream ss(st); // 分割每个单词
string Word; // 保存每个单词
while (ss >> Word)
FW[Word]++;
map<string, int>::iterator m;
for (m = FW.begin(); m != FW.end(); m++)
cout << m->first << " -> "
<< m->second << "\n";
}
// Driver code
int main()
{
string s = "geeks for geeks geeks contribution placements";
cout << " Number of words are: " << countWords(s) << endl;
printFrequency(s);
return 0;
}
编译和运行结果:
$ g++ 07_stringstream.cpp -o 07_stringstream.o -std=c++11
$ ./07_stringstream.o
Number of words are: 6
contribution -> 1
for -> 1
geeks -> 3
placements -> 1