chapter 8
1、
ifstream和istringstream都继承自istream。由此,可以对一个ifstream或istringstream对象调用getline,也可以使用>>从一个ifstream或istringstream对象中读取数据。类似ofstream和ostringstream继承自ostream。
2、
ofstream out1, out2;
out1 = out2; //错误,不能对流对象赋值
oftream = print(oftream); // 错误,不能初始化ofstream参数
out2 = print(out2); //错误,不能拷贝流对象
由于不能拷贝IO对象,因此也不能将形参或返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。但不能是const类型。
3、
每个输出流都管理一个缓存区,用来保存程序读写的数据。
由于设备的写操作可能很耗时,允许操作系统将多个输出操作组合为单一的设备写操作可以带来很大的性能提升。
当一个fstream对象被销毁时,close会自动被调用。
保留被ofstream打开的文件中已有数据的唯一方法是显式指定app或in模式。
4、
sstream头文件定义了三个类型来支持内存IO,这些类型向string写入数据。从string读取数据,就像string是一个IO流一样。
istringstream从string读取数据,ostringstream向string写入数据。stringstream既可以从string读数据也可以从string写数据。头文件sstream中的类型继承自iostream定义的类型。
stringstream还增加些操作:
strm.str() 返回strm所保存的string的拷贝
1、
ifstream和istringstream都继承自istream。由此,可以对一个ifstream或istringstream对象调用getline,也可以使用>>从一个ifstream或istringstream对象中读取数据。类似ofstream和ostringstream继承自ostream。
2、
ofstream out1, out2;
out1 = out2; //错误,不能对流对象赋值
oftream = print(oftream); // 错误,不能初始化ofstream参数
out2 = print(out2); //错误,不能拷贝流对象
由于不能拷贝IO对象,因此也不能将形参或返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。但不能是const类型。
3、
每个输出流都管理一个缓存区,用来保存程序读写的数据。
由于设备的写操作可能很耗时,允许操作系统将多个输出操作组合为单一的设备写操作可以带来很大的性能提升。
当一个fstream对象被销毁时,close会自动被调用。
保留被ofstream打开的文件中已有数据的唯一方法是显式指定app或in模式。
4、
sstream头文件定义了三个类型来支持内存IO,这些类型向string写入数据。从string读取数据,就像string是一个IO流一样。
istringstream从string读取数据,ostringstream向string写入数据。stringstream既可以从string读数据也可以从string写数据。头文件sstream中的类型继承自iostream定义的类型。
stringstream还增加些操作:
strm.str() 返回strm所保存的string的拷贝
strm.str(s) 将string s拷贝到strm中,返回void
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include "Chapter8.h"
#define NUM811
using namespace std;
/*8.1*/
istream &read(istream &is){
string word;
while(is >> word)
cout << word <<endl;
is.clear();
return is;
}
/*8.4*/
int readFile(const string &fileName, vector<string> &vec){
ifstream inf(fileName.c_str());//c99编译器ifstream只接受const char*
if(inf){
string buf;
while(getline(inf, buf))
vec.push_back(buf);
}else{
cerr << "error: can not open the file: " << fileName <<endl;
return -1;
}
return 0;
}
/*8.5*/
int readFilePerWord(const string &fileName, vector<string> &vec){
ifstream inf(fileName.c_str());//c99编译器ifstream只接受const char*
if(inf){
string buf;
while(inf >> buf)
vec.push_back(buf);
}else{
cerr << "error: can not open the file: " << fileName <<endl;
return -1;
}
return 0;
}
/*8.10*/
int LineToVector(string fileName, vector<string> &vec){
string line, word;
ifstream inf(fileName.c_str());
if(inf){
string buf;
while(getline(inf, buf)){
vec.push_back(buf);
}
}else{
cerr << "error: can not open the file: " << fileName <<endl;
}
}
/*8.11*/
struct PersonInfo{
string name;
vector<string> phones;
};
int main(int argc, char** argv){
/*8.2*/
#ifdef NUM82
istream &is = read(cin);
cout << is.rdstate() << endl;
#endif
/*8.3*/
#ifdef NUM83
cout <<"当出现错误状态时,比如badbit(系统级错误)failbit(置位)eofbit(文件结束). "<<endl;
#endif
/*8.4*/
#ifdef NUM84
vector<string> vec;
readFile("./fact.cc", vec);
for(size_t it = 0; it < vec.size(); ++it)
cout << vec[it] <<endl;
#endif
/*8.5*/
#ifdef NUM85
vector<string> vec;
readFilePerWord("./fact.cc", vec);
for(size_t it = 0; it < vec.size(); ++it)
cout << vec[it] << " ";
cout <<endl;
#endif
/*8.6*/
#ifdef NUM86
ifstream input(argv[1]);
Sales_data total;
if(read(input, total)){
Sales_data trans;
while(read(input, trans)){
if(total.isbn() == trans.isbn())
total.combine(trans);
else{
print(cout, total) <<endl;
total = trans;
}
}
print(cout, total) << endl;
}else
cerr << "No data. "<<endl;
#endif
/*8.7*/
#ifdef NUM87
ifstream input(argv[1]);
ofstream output(argv[2]);
Sales_data total;
if(read(input, total)){
Sales_data trans;
while(read(input, trans)){
if(total.isbn() == trans.isbn())
total.combine(trans);
else{
print(output, total) <<endl;
total = trans;
}
}
print(output, total) << endl;
}else
cerr << "No data. "<<endl;
#endif
/*8.8*/
#ifdef NUM88
ifstream input(argv[1]);
ofstream output(argv[2], ofstream::app); //app:每次写操作均定位到文件末尾
Sales_data total;
if(read(input, total)){
Sales_data trans;
while(read(input, trans)){
if(total.isbn() == trans.isbn())
total.combine(trans);
else{
print(output, total) <<endl;
total = trans;
}
}
print(output, total) << endl;
}else
cerr << "No data. "<<endl;
#endif
/*8.9*/
#ifdef NUM89
string line;
cout << "Enter a line of text: "<<endl;
while(getline(cin, line)){
istringstream record(line);
read(record);
}
#endif
/*8.10*/
#ifdef NUM810
vector<string> vec;
string fileName, word;
cout <<"Enter filename: "<<endl;
cin >> fileName;
LineToVector(fileName, vec);
for(vector<string>::iterator it = vec.begin(); it != vec.end(); ++it){
istringstream record(*it);
while(record >> word)
cout << word <<endl;
record.clear();
}
#endif
/*8.11*/
#ifdef NUM811
string line, word;
vector<PersonInfo> people;
istringstream record;
while(getline(cin, line)){
PersonInfo info;
record.clear(); //清空流
record.str(line);
record >> info.name;
while(record >> word)
info.phones.push_back(word);
people.push_back(info);
}
for(vector<PersonInfo>::iterator it = people.begin(); it != people.end(); ++it){
cout << it->name << " ";
for(vector<string>::iterator pit = it->phones.begin(); pit != it->phones.end(); ++pit)
cout << *pit <<" ";
cout<<endl;
}
#endif
/*8.12*/
#ifdef NUM812
cout <<"因为我们需要一个集合类。"<<endl;
#endif
/*8.13*/
#ifdef NUM813
string line, word;
vector<PersonInfo> people;
string fileName = "./book_sales";
ifstream inf(fileName.c_str());
if(inf){
while(getline(inf, line)){
PersonInfo info;
record.clear();
istringstream record(line);
record >> info.name;
while(record >> word)
info.phones.push_back(word);
people.push_back(info);
}
for(vector<PersonInfo>::iterator it = people.begin(); it != people.end(); ++it){
cout << it->name << " ";
for(vector<string>::iterator pit = it->phones.begin(); pit != it->phones.end(); ++pit)
cout << *pit <<" ";
cout<<endl;
}
}else{
cerr << "error: can not open the file: " << fileName <<endl;
}
#endif
/*8.14*/
#ifdef NUM814
cout <<"写入数据是并不需要改变,所以可以用const类型;同时auto&引用更为简洁. "<<<endl;
#endif
return 0;
}
参考资料:
c++ primer中文版第五版,电子工业出版社。
c++ primer第四版习题解答,人民邮电出版社。