第八章 标准IO库
8.1面向对象的标准库
1. #include <iostream>
#include <sstring> // 从iostream继承
#include <fstream> // 从iostream继承
2. 国际字符支持
char有相应的wchar_t
wostream wistream wiostream <iostream>
wifstream wofstream wfstream <fstream>
wistringstream wostingstream wstringstream <sstream>
3. IO对象不能复制或赋值
不能放在vector或其他容器中
不能作为形参,必须是引用或指针(返回值也要是引用)
形参也是非const的,因为IO对象的读写会改变状态
8.2条件状态
strm::iostate
strm::badit //系统级的故障
strm::failbit //可恢复的错误
strm::eofbit //遇到文件结束符时和failbit同时设置
s.eof() //四种流状态
s.bad()
s.fail()
s.good()
s.clear() // 将条件重置为有效状态
s.clear(f)
s.setstate(f) // 打开某个指定的条件
s.rdstate() // 返回当前条件 返回类型strm::iostate
8/3输出缓冲区的管理1.cout << “abc” << flush; //刷新流
cout << “abc” << ends; //插入空字符null,然后刷新
cout << “abc” << endl; //输出一个换行符并刷新流
2.unitbuf刷新所有输出,nounitbuf将流恢复为正常的、由系统管理的缓冲区刷新方式
cout<<unitbuf<<"first"<<"second"<<nounitbuf;
3.交互式程序cin与cout绑定:任何cin读操作都会首先刷新cout关联的的缓冲区
tie函数,一个流调用tie将自己绑定在传过来的实参流上,则它的任何IO操作都会刷新实参所关联的缓冲区
cin.tie(&cout);
ostream *old_tie = cin.tie();
cin.tie(0); // 释放tie
cin.tie(&cerr);
cin.tie(0);
cin.tie(old_tie); // 重新与cout绑定
8.4 文件的输入和输出
调用open成员函数将已存在的fstream对象与特定文件绑定
ifstream infile(ifile.c_str()) 或 ifstream infile; infile.open("in") //in是当前目录存在的文件
1.检查文件打开是否成功
if(!infile){
cerr<<"error: unable to open input file:"<<ifile<<endl;
return -1;
}
2.将文件流与新文件重新捆绑必须先关闭现在的文件,然后打开另一个
ifstream infile("in");
infile.close();
infile.open("next");
3.清除文件流的状态
ifstream input;
vector<string>::const_iterator it=files.begin();
while(it!=files.end()){
input.open(it->c_str());
if(!input)
break;
while(input>>s)
process(s);
input.close();
input.clear();
++it;
} //重用已存在的流对象,每次循环是记得关闭和清空文件流
4.文件模式
n // ifstream和fstream , ifstream默认以in打开
out // ofstream fstream 会清空数据相当于也打开了trunc,ofstream默认以out打开
app // ofstream 追加
ate //打开后定位在尾
trunc // ofstream 清空数据
binary // 以二进制模式进行IO操作
只要调用open函数,就要设置文件模式,可以显式也可隐式的设置。
下面代码不清楚in的当前状态,首先调用close和clear将这个流设置为有效状态
ifstream& open_file(ifstream &infile,const string &filename) {
infile.close();
infile.clear();
infile.open(filename.c_str());
return in;
}
8.5字符串流特定操作
stringstream strm;
stringstream strm(s);
strm.str(); // 返回那个string对象
strm.str(s);
1.同时实现操作一个和一行单词
while (getline(cin, line)) {
istringstreamistrm(line);
while(istrm >> word) { // 处理这行中的每个单词
.....
}
}
2. stringstream可以提供转换和格式化
int val1 = 512, val2 = 1024;
ostringstream out ;
out << "val1:" << val1<< "\nval2:" << val2 << "\n";
istringstream in(out.str()); // 关联到这行字符val1:21\nval2:23
string dump;
in >> dump >> val1 >> dump>> val2;
cout << val1 << " "<< val2 << endl;
3. 文件读入,每行作为一个元素放到vector<string>中,再istringstream对象初始化为每个元素,处理每个单词,输出; 这都是很简单的程序
istringstream istr;
string word;
for (vector<string>::const_iterator it= svec.begin(); it != svec.end(); ++it) {
istr.str(*it);
while (istr >> word) {
cout << word << “ ” ;
}
istr.clear(); // 定义在外面,所以将流设置为有效状态
}