考虑这样的程序,它有一个vector对象,包含一些要打开并读取的文件名,程序要对每个文件中存储的单词做一些处理。假设vector对象命名为files,程序也许会有如下的循环:
ifstream input;
vector<string>::const_iterator it=files.begin();
//for each in the vector
while(it !=files.end()) {
input.open(it->c_str()); //open the file
///if the file is ok,read and "process"the input
if(!input)
break;
while(input>>s) //do the work on this file
process(s);
input.close(); //close file when we're done with it
input.clear(); //reset state to ok
++it; //increment iterator to get next file
}
如果遇到文件结束符或其他错误,将设置流的内部状态,以便之后不允许再对该流做读写操作。关闭流并不能改变流对象的内部状态。如果最后的读写操作失败了,读写的状态将保持为错误模式,直到执行clear操作重新恢复流的状态为止。调用clear后,就像重新创建了该对象一样。如果打算重用已存在的流对象,那么while循环必须在每次 循环时记得关闭(close)文件和清空(clear)文件流状态。
一个打开并坚持输入文件的程序代码:我们编写一个名为open_file的函数实现这个功能。这个函数有两个引用形参,分别是ifstream和string类型,其中string 类型的引用形参存储于指定ifstream对象关联的文件名:
//open in binding it to the given file
ifstream& open_file(ifstream& in,const string& file)
{
in.close(); //close in case it was already open
in.clear(); //clear any existing errors
//if the open fails,the stream will be in an invalid state
in.open(file.c_str()); //open the file we were given
return in; //condition state is good if open succeeded
}
由于不清楚流in的当前状态,因此首先调用close和clear将这个流设置为有效状态。然后尝试打开给定的文件。如果打开失败,流的条件状态将标志这个流是不可用的。最后返回流对象in,此时,in要么已经与指定文件绑定起来了,要么处于错误条件状态。