IO相关3(string流)
sstream 头文件定义了三个类型来支持内存 IO,这些类型可以向 string 写入数据,从 string 读取数据,就像 string 是一个 IO 流一样。
istringstream 从 string 读取数据,ostringstream 向 string 写入数据,stringstream 既可以从 string 读取数据也可以向 string 写入数据。类似于 fstream,sstream 中定义的类型也都是继承自 iostream 中的类型。除了继承来的操作,sstream 中定义的类型还增加了一些成员来管理与流相关的 string。可以对 stringstream 对象调用这些操作,但不能对其他 IO 类型调用这些操作:
1 sstream strm;//strm是一个未绑定的stringstream对象.sstream是头文件sstream中定义的一个类型 2 sstream strm1(s);//strm是一个sstream对像,保存string s的一个拷贝.此构造函数是explicit的 3 strm.str();//返回strm所保存的string拷贝 4 strm.str(s);//将string s拷贝到strm中.返沪void
使用 istringstream:
假定有一个文件,列出了一些人和它们的电话号码。某些人只有一个号码,而另一些人则有多个——家庭电话,工作电话,移动电话等。我们输入的文件可能是:
morgan 2017347 72849289
jfsl 7823434
jfkds 7384534 58349578 59308509
每条记录都以一个人名开始,后面跟着一个或多个电话号码。我们首先定义一个简单的类来描述输入数据:
1 //成员默认为共有 2 struct person_info{ 3 string name;//存储人名 4 std::vector<string> phones;//存储电话号码 5 };
1 #include <iostream> 2 #include <sstream> 3 #include <vector> 4 using namespace std; 5 6 //成员默认为共有 7 struct person_info{ 8 string name;//存储人名 9 std::vector<string> phones;//存储电话号码 10 void print(void) const{ 11 cout << name; 12 for(const auto p : phones){ 13 cout << " " << p; 14 } 15 cout << endl; 16 } 17 }; 18 19 int main(void){ 20 string line, word;//分别保存来自输入的一行和单词 21 std::vector<person_info> people;//保存来自输入的所有记录 22 23 while(getline(cin, line)){ 24 person_info info;//创建一个保存此记录的数据对象 25 istringstream record(line);//将记录绑定到刚读入的行 26 record >> info.name; 27 while(record >> word){ 28 info.phones.push_back(word); 29 } 30 people.push_back(info);//将此记录追加到people末尾 31 // info.print(); 32 } 33 34 for(const auto info : people){ 35 info.print(); 36 } 37 return 0; 38 }
使用 ostringstream:
当我们逐步构造输出,希望最后一起打印时,ostringstream 是很有用的。如:在上一个例子中,我们可能像逐个验证电话号码并改变其格式。如果所有号码都是有效的,我们希望输出一个新的文件,包含改变格式后的号码。对于那些无效号码,我们不会将它们输出到新文件中,而是打印一条包含人名和无效号码的错误信息。
由于我们不希望输出有无效号码的人,因此对于每个人,知道验证完所有电话号码后才可以进行输出操作。但是我们可以先将输出内容 "写入" 到一个内存 ostringstream 中:
1 #include <iostream> 2 #include <sstream> 3 #include <vector> 4 using namespace std; 5 6 //成员默认为共有 7 struct person_info{ 8 string name;//存储人名 9 std::vector<string> phones;//存储电话号码 10 void print(void) const{ 11 cout << name; 12 for(const auto p : phones){ 13 cout << " " << p; 14 } 15 cout << endl; 16 } 17 }; 18 19 bool valid(const string &s){ 20 21 } 22 23 bool format(const string &s){ 24 25 } 26 27 int main(void){ 28 string line, word;//分别保存来自输入的一行和单词 29 std::vector<person_info> people;//保存来自输入的所有记录 30 31 while(getline(cin, line)){ 32 person_info info;//创建一个保存此记录的数据对象 33 istringstream record(line);//将记录绑定到刚读入的行 34 record >> info.name; 35 while(record >> word){ 36 info.phones.push_back(word); 37 } 38 people.push_back(info);//将此记录追加到people末尾 39 // info.print(); 40 } 41 42 for(const auto &entry : people){ 43 ostringstream formatted, bad_nums; 44 for(const auto &nums : entry.phones){ 45 if(!valid(nums)) bad_nums << " " << nums; 46 else formatted << " " << format(nums); 47 } 48 if(bad_nums.str().empty()) cout << entry.name << " " << formatted.str() << endl; 49 else cout << "input error: " << entry.name << " invalid number(s) " << bad_nums.str() << endl; 50 } 51 return 0; 52 }
sstream 通常用于格式转换: