1)首先来说,stringstream特有的操作:
sstream strm;//strm是一个未绑定的stringstream对象。sstream是头文件sstream中定义的一个类型
sstream strm(s);//strm是一个sstream对象,保存string s的拷贝。此构造函数是explicit的
strm.str();//返回strm所保存的string的拷贝
strm.str(s);//将string s 拷贝到strm中。返回void
2)istringstream从string中读取数据,当我们的工作是处理行内的单个单词时,通常可以使用istringstream。
换种说法也就是,istringstream可以创建一个对象,该对象可以绑定一行字符串,行内用空格为分隔符隔开,可以处理单个字符串。
假定一个文件,列出一些人的姓名和家庭、工作、移动号码,号码不确定。
#include<iostream>
#include<string>
#include<vector>
#include<fstream>
#include<sstream>
using namespace std;
struct PersonInfo
{
string name;//表示人名
vector<string>phones;//vector保存此人的电话号码
};
int main() {
string line, word;//分别保存来自输入的一行和一个单词
vector<PersonInfo>people;
//我们使用getline从标准输入读取整条记录。如果getline成功,则line中保存着从输入文件而来的一条记录
while (getline(cin, line)) {
PersonInfo info;//创建一个保存此纪录数据的对象
istringstream record(line);//将一个istringstream与刚读的文本行进行绑定
//这样就可以使用在此istringstream上使用输入运算符来读取当前记录的每个元素
//sstream strm(s);strm是一个sstream对象,保存string s的拷贝。此构造函数是explicit的
//record是一个istringstream对象,从string s中读取数据。
record >> info.name;
while (record >> word)
{
info.phones.push_back(word);
}
people.push_back(info);
}
return 0;
}
内层while循环的工作方式与cin的循环方式很像,不同之处在于,此循环是从一个string读取数据,而不是标准输入读取数据。当string中数据全部读出后,同样会触发“文本结束”信号,在record上的下一个输入操作会失败。
3)当我们逐步构造输出,希望最后一起打印时,ostringstream就派上用场了。
for (const auto& entry : people)//对于people中的每一项
{
ostringstream formatted, badNums;//每个循环创建ostringstream对象
for (const auto& nums : entry.phones)//对于每个电话号码
{
if (!vaild(nums))
badNums << " " << nums;//将数的字符串形式存入badNums
else
formatted << " " << format(nums);//将格式化的字符串写入formatted
}
//我们使用标准的输出运算符<<向这些对象写入数据,但这些“写入”操作实际上转换为string操作,分别向formatted和badNums中的string对象添加字符
if (badNums.str().empty())
os << entry.name << " " << formatted.str() << endl;
else
cerr << "input error:" << entry.name << "invaild number(s)" << badNums.str() << endl;
}
小结
istringstream | istringstream从string中读取数据,当我们的工作是处理行内的单个单词时,通常可以使用istringstream |
---|---|
ostringstream | 当我们逐步构造输出,希望最后一起打印时,ostringstream就派上用场了 |
isreingstream从string中读取数据,ostringstream向string中写入数据