文件输入输出

  头文件fstream定义了三个类型来支持文件IO:ifstream从一个给定的文件读取数据,ofstream向一个给定文件写入数据,以及fstream可以读写给定文件。

表1:fstream特有操作

fstream strm; 创建一个未绑定的文件流。fstream是头文件中定义的一个类型
fstream fstrm(s); 创建一个fstream,并打开名为s的文件。s可以是string类型,或者是一个指向C风格字符串类型的指针。这些构造函数都是explicit的。默认的文件模式依赖于fstream的模式。
fstream fstrm(s, mode); 与前一个构造函数类似,都是以mode模式打开文件
fstrm.open(s) 打开一个名为s的文件,并与fstrm绑定。s可以是一个string或者一个指向C风格字符串的指针。默认的文件模式依赖于fstream的类型
fstrm.close() 关闭与fstrm绑定的文件。返回void
fstrm.is_open() 返回一个bool值,指出与fstrm关联的文件是否成功打开且未关闭

使用文件流对象

  每个文件流类都定义了一个open成员函数. 在创建文件流对象时, 可以直接提供文件名(可选), 当提供了文件名时, 会自动调用open().

1
2
ifstream in(ifile); //构造一个ifstream类型的流对象并打开文件
ofstream out; //构造一个输出文件流, 但是未与任何文件关联

  在新的C++标准中, 文件名可以是库类型string对象, 也可以是C风格字符数组. 旧版本的标准库只允许是C风格字符数组.

用fstream代替iostream&

成员函数open和close

1
2
3
ifstream in(ifile);
ofstream out;
out.open(ifile + ".copy"); //打开指定文件

  如果调用open失败. failbit会被置位. 因为调用open可能会失败, 因此需要养成进程检验open成功与否的好习惯.

1
if(out)

  一旦一个文件流打开了, 它就保持与文件的关联. 如果再对一个已经打开的文件流调用open将会失败, 并会导致failbit被置位. 为了将文件流关联到另外一个文件,必须先关闭已经关联的文件流.

自动构造和析构
  考虑这样一个程序:

1
2
3
4
5
6
7
for(auto p = argc + 1; p != argv + argc; ++p){
ifstream input(*p) //创建输入流并打开文件
if(input)
process(input);
else
cerr << "couldn't open: " + string(*p);
}

  这样,每一个循环都会构造一个新的名为input的ifstream对象, 并打开它来读取对应文件. 但是由于input是while的局部变量, 因此在每一次循环都会创建和销毁一次. 当一个fstream离开其作用域时, 与之关联的文件会自动关闭. 在下一步循环中, input会被自动创建. 当一个fstream被销毁时, close会自动被调用

文件模式