二:文件输入输出。
(1) 使用文件流对象:
头文件fstream定义了三个类型来支持文件IO:ifstream从一个给定的文件中读取数据,ofstream向一个给定的文件中写入数据,以及fstream可以读写给定文件。
这些类型提供的操作和cin、cout的操作一样,我们可以用<<和>>来读写文件,可以用getline从一个ifstream读取数据。
fstream头文件还定义了其他的操作:
fstream fstrm;// 创建一个未绑定的文件流,fstream是fstream头文件中定义的一个类型
fstream fstrm(s);// 创建一个fstream,并打开名为s的文件,s可以是string类型,也可以是指向C风格字符串数组的指针,默认的文件模式mode依赖于fstream的类型,这些构造函数都是explicit的
fstream fstrm(s, mode);// 与上一个类似,但按指定的mode打开文件
fstrm.open(s);// 打开名为s的文件,并将文件与fstrm绑定,函数返回void。
fstrm.close();// 关闭与fstrm关联的文件,返回void
fstrm.is_open();// 返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭
使用文件流对象:
我们要读写文件时,可以定义一个文件流对象,创建对象时,我们可以提供文件名(可选的),如果提供了一个文件名,则open成员函数会自动被调用:
ifstream in(infile); // 构造一个ifstream对象并打开给定名为infile的文件
<pre>ofstream out; // 输出文件未关联任何文件
如果我们定义了一个空文件流对象,即定义对象但未关联文件。可以随后调用open成员函数来关联到一个文件:
ifstream in(ifile); // 构造一个ifstream对象并打开给定名为ifile的文件
ofstream out; // 输出文件未关联任何文件
out.open(ifile + ".copy"); //打开指定文件
如果调用open失败,failbit会被置位。进行open是否成功的检测通常是一个比较好的习惯:
if (out) // 检查open是否成功
//... open成功,可以使用文件了
这个判断条件和我们判断cin类似。
实际上,对一个已打开的文件流调用open会失败,倒置failbit被置位。随后试图使用文件流的操作都将失败!因此我们要将流对象和文件关联起来时,必须首先确定关闭已经关联的文件,然后再关联新的文件:
in.close(); // 关闭文件
in.open(ifile + "2"); // 打开另外一个文件
当一个fstream对象被销毁时,close成员函数自动被调用!
(2). 文件模式(mode)
每个流都有一个关联的文件模式,用来指出如何使用文件:
in |
以读方式打开 |
out |
以写方式打开 |
app |
每次写操作前均定位到文件末尾 |
ate |
打开文件后立即定位到文件末尾 |
trunc |
截断文件 |
binary |
以二进制方式进行IO |
指出文件模式有如下限制:
# 只可以对ofstream或fstream对象设定out模式;
# 只可以对ifstream或fstream对象设定in模式;
# 只有当out也被设定时才可以设定trunc模式;
# 只要trunc没被设定,就可以设定app模式。在app模式下,即使没有显示指定out模式,文件也总是以输出方式被打开
# 默认情况下,即使没有指定trunc模式,以out模式打开的文件也被截断。我们可以必须同时指定app模式才可以保留以out模式打开的文件的内容,这样只会将数据追加到文件末尾; 或者同时指定in模式,同时读写。
# atr和binary模式可用于任何类型的文件流对象。
每个流类型都定义了一个默认的文件模式,ifstream关联的文件以in模式打开,ofstream关联的文件以out打开,fstream关联的文件以in和out打开。
阻止一个ofstream清空文件内容的方式是同时指定app或in模式:
std::ofstream out("test.txt", std::ofstream::out | std::ofstream::app);
<pre name="code" class="cpp" style="font-weight: bold;">std::ofstream out("test.txt", std::ofstream::out | std::ofstream::in);
对于一个给定流,每次打开文件时,都可以改变其文件模式:
同样的,我们可以同时指定app模式,来阻止out调用open时清空文件内容的情况:
out.open("test.txt", std::ofstream::app);
如果在open一个文件时未指定文件模式,则使用默认值。
三、string流
sstream头文件定义了三个类型来支持内存IO。
istringstream从string中读取数据,ostringstream向string写入数据,stringstream可以进行读或写。
sstream strm; // strm未绑定文件,sstream是一个stringstream对象(下同)
sstream strm(s); // strm保存string s的一个拷贝,此构造函数时explict的
strm.str(); // 返回strm保存的string对象的拷贝
strm.str(s); // 将string s拷贝到strm中,返回void
使用istringstream
string line,word;
while (getline(cin,line))
{
istringstream stream(line);
while (stream >> word)
{
// do per-word ...
}
}
将一个istringstream对象与所读取的行绑定起来,这样只需使用普通的string输入操作符即可读出每行中的单词。
而ostringstream和它使用类似。