C++中的文件输入/输出(4)
原作:Ilia Yordanov, loobian@cpp-home.com
检测输入/输出的状态标志
在此我不打算解释“标志(flags)”一词的含义,不过假如你真的完全不理解关于这方面的概念,那么将本章读过一遍之后也许你对此会得到一些认识,我也相信你同样能理解这部分的理论。尽管如此,如果你还是不明白标志在C++中的含义,我推荐你阅读一些关于这个主题的资料。
好,让我们开始吧。
C++中负责的输入/输出的系统包括了关于每一个输入/输出操作的结果的记录信息。这些当前的状态信息被包含在io_state类型的对象中。io_state是一个枚举类型(就像open_mode一样),以下便是它包含的值(译注:表中第一列为枚举值的名称,第二列为该值相应含义的描述):
godbit
无错误
Eofbit
已到达文件尾
failbit
非致命的输入/输出错误
badbit
致使的输入/输出错误
有两种方法可以获得输入/输出的状态信息。一种方法是通过调用rdstate()函数,它将返回当前状态的错误标记(上表中提到的)。例如,假如没有任何错误,则rdstate()会返回goodbit.
另一种方法则是使用下面任何一个函数来检测相应的输入/输出状态:
bool bad();
bool eof(); //还记得它么?“不断读取文件内容直到到达文件末尾!”
bool fail(); //噢,这也是老朋友……检测一个打开操作是否成功
bool good();
假如badbit标志被标设(译注:原文为“If the badbit flag is up”,这里将“is up”译为“标设”,意即出现了badbit对应的错误,badbit状态被置为当前的错误状态,下同),则bad()函数返回true;假如failbit标志被标设,则fail()函数返回true;假如没有错误发生(goodbit标志被标设),则good()函数返回true;假如操作已经到达了文件末尾(eofbit被标设),则eof()函数返回true.
如果错误发生,你必须清除这些错误状态,以使你的程序能正确适当地继续运行——如果你这么打算的话。要清除错误状态,需使用clear()函数。此函数带一个参数,它是你将要设为当前状态的标志值。假使你想让你的程序“清清爽爽”地运行下去,只要将ios::goodbit作为实参。你将在以下内容中看到示例代码。
我将向你展示示例代码,以巩固你所学到的理论知识。
示例1:简单的状态检测
// 实际应用中可将 FileStream替换成你相应在使用的文件流句柄
if(FileStream.rdstate() == ios::eofbit)
cout << "End of file!\n";
if(FileStream.rdstate() == ios::badbit)
cout << "Fatal I/O error!\n";
if(FileStream.rdstate() == ios::failbit)
cout << "Non-fatal I/O error!\n";
if(FileStream.rdstate() == ios::goodbit)
cout << "No errors!\n";
示例2:clear()函数
#include <fstream.h>
void main()
{
ofstream File1("file2.txt"); //建立file2.txt
File1.close();
// 下面的检测代码将会返回错误,这是因为我使用了ios::noreplace打开模式
// 它模式在试图打开一个已存在的文件时会返回错误
ofstream Test("file2.txt",ios::noreplace);
// 上一行将导致ios::failbit错误,我们这就将其演示出来
if(Test.rdstate() == ios::failbit)
cout << "Error...!\n";
Test.clear(ios::goodbit); // 将当前状态重置为ios::goodbit
if(Test.rdstate() == ios::goodbit) // 检测程序是否已经正确地施行了设置
cout << "Fine!\n";
Test.clear(ios::eofbit); // 将状态标志设为ios::eofbit. 无实际用途.
if(Test.rdstate() == ios::eofbit) // 检测是否已经正确地施行了设置 cout << "EOF!\n";
Test.close();
}
除了使用标记值判断,你也可以使用函数(译注:指bad()、eof()、fail()、good()这些函数)的形式进行判断,两者实际上是一样的——都是检测某个标记是否被标设。这些函数前面已经介绍过,我就不再重复了。如果你对如何使用它们还不是十分确定,那就重新回顾一下本教程中我曾经为你演示的应该如何检测一个文件打开操作是否成功的那部分内容。在那里我就使用了fail()函数。