err_7848.htm
来自「C++标准库 C++标准库 C++标准库 C++标准库」· HTM 代码 · 共 213 行
HTM
213 行
<HTML><HEAD><TITLE>2.4 Error State of Streams</TITLE></HEAD><BODY><A HREF="ug2.htm"><IMG SRC="images/banner.gif"></A><BR><A HREF="for_5394.htm"><IMG SRC="images/prev.gif"></A><A HREF="booktoc2.htm"><IMG SRC="images/toc.gif"></A><A HREF="fil_2309.htm"><IMG SRC="images/next.gif"></A><BR><STRONG>Click on the banner to return to the user guide home page.</STRONG><H2>2.4 Error State of Streams</H2><P>It probably comes as no surprise that streams have an error state. Our examples have avoided it to this point, so we'll deal with it now. When an error occurs, flags are set in the state according to the general category of the error. Flags and their error categories are summarized in Table 5 below:</P><CENTER><TABLE BORDER CELLSPACING=3 CELLPADDING=3><TR VALIGN=top><TD><B>iostate flag</B><BR></TD><TD><B>Error category</B><BR></TD></TR><TR VALIGN=top><TD><SAMP>ios_base::goodbit</SAMP><BR></TD><TD>Everything's fine<BR></TD></TR><TR VALIGN=top><TD><SAMP>ios_base::eofbit</SAMP><BR></TD><TD>An input operation reached the end of an input sequence<BR></TD></TR><TR VALIGN=top><TD><SAMP>ios_base::failbit</SAMP><BR></TD><TD>An input operation failed to read the expected character, or<BR>An output operation failed to generate the desired characters<BR></TD></TR><TR VALIGN=top><TD><SAMP>ios_base::badbit</SAMP><BR></TD><TD>Indicates the loss of integrity of the underlying input or output sequence<BR></TD></TR></TABLE></CENTER><P>Note that the flag <SAMP>ios_base::goodbit</SAMP> is not really a flag; its value, zero, indicates the absence of any error flag. It means the stream is OK. By convention, all input and output operations have no effect once the stream state is different than zero.</P><P>There are several situations when both <SAMP>eofbit</SAMP> and <SAMP>failbit</SAMP> are set; however, the two have different meanings and do not always occur in conjunction. The flag <SAMP>ios_base::eofbit</SAMP> is set when there is an attempt to read past the end of an input sequence. This occurs in the following two typical examples:</P><OL><LI><P>Assume the extraction happens character-wise. Once the last character is read, the stream is still in good state; <SAMP>eofbit</SAMP> is not yet set. Any subsequent extraction, however, will be considered an attempt to read past the end of the input sequence. Thus, <SAMP>eofbit</SAMP> will be set.</P></LI><LI><P>If you do not read character-wise, but extract an integer or a string, for example, you will always read past the end of the input sequence. This is because the input operators read characters until they find a separator, or hit the end of the input sequence. If the input contains the sequence <SAMP>... 912749<eof></SAMP> and an integer is extracted, <SAMP>eofbit</SAMP> will be set. </P></LI></OL><P>The flag <SAMP>ios_base::failbit</SAMP> is set as the result of a read or write operation that fails. For example, if you try to extract an integer from an input sequence containing only white spaces, the extraction fails, and the <SAMP>failbit</SAMP> is set. Let's see whether <SAMP>failbit</SAMP> would be set in the previous examples:</P><OL><LI><P>After reading the last available character, the extraction not only reads past the end of the input sequence; it also fails to extract the requested character. Hence, <SAMP>failbit</SAMP> is set in addition to <SAMP>eofbit</SAMP>.</P></LI><LI><P>Here it is different. Although the end of the input sequence is reached by extracting the integer, the input operation does not fail and the desired integer will indeed be read. Hence, in this situation only the <SAMP>eofbit</SAMP> will be set.</P></LI></OL><P>In addition to these input and output operations, there are other situations that can trigger failure. For example, file streams set <SAMP>failbit</SAMP> if the associated file cannot be opened (see <A HREF="fil_2309.htm">Section 2.5</A>).</P><P>The flag <SAMP>ios_base::badbit</SAMP> indicates problems with the underlying stream buffer. These problems could be:</P><UL><LI><P><B><I>Memory shortage</I></B>. There is no memory available to create the buffer, or the buffer has size zero for other reasons<A HREF="endnote2.htm#fn21">[21]</A>, or the stream cannot allocate memory for its own internal data, as with <SAMP>iword</SAMP> and <SAMP>pword</SAMP>.</LISTFN></LI><LI><P><B><I>The underlying stream buffer throws an exception</I></B>. The stream buffer might lose its integrity, as in memory shortage, or code conversion failure, or an unrecoverable read error from the external device. The stream buffer can indicate this loss of integrity by throwing an exception, which is caught by the stream and results in setting the <SAMP>badbit</SAMP> in the stream's state.</P></LI></UL><P>Generally, you should keep in mind that <SAMP>badbit</SAMP> indicates an error situation that is likely to be unrecoverable, whereas <SAMP>failbit</SAMP> indicates a situation that might allow you to retry the failed operation. The flag <SAMP>eofbit</SAMP> simply indicates the end of the input sequence.</P><P>What can you do to check for such errors? You have two possibilities for detecting stream errors:</P></LI><UL><LI><P>You can declare that you want to have an exception raised once an error occurs in any input or output operation, or</P></LI><LI><P>You can actively check the stream state after each input or output operation.</P></LI></UL><P>We will explore these possibilities in the next two sections.</P><A NAME="2.4.1"><H3>2.4.1 Checking the Stream State</H3></A><P>Let's first examine how you can check for errors using the stream state. A stream has several member functions for this purpose, which are summarized with their effects in the Table 6:</P><CENTER><TABLE BORDER CELLSPACING=3 CELLPADDING=3><TR VALIGN=top><TD><B><I><B><I>ios_base</I></B></B></I> <B>member function</B><BR></TD><TD><B>Effect</B><BR></TD></TR><TR VALIGN=top><TD><SAMP>bool good()</SAMP><BR></TD><TD>True if no error flag is set<BR></TD></TR><TR VALIGN=top><TD><SAMP>bool eof()</SAMP><BR></TD><TD>True if <SAMP>eofbit</SAMP> is set<BR></TD></TR><TR VALIGN=top><TD><SAMP>bool fail()</SAMP><BR></TD><TD>True if <SAMP>failbit</SAMP> or <SAMP>badbit</SAMP> is set<BR></TD></TR><TR VALIGN=top><TD><SAMP>bool bad()</SAMP><BR></TD><TD>True if <SAMP>badbit</SAMP> is set<BR></TD></TR><TR VALIGN=top><TD><SAMP>bool operator!()</SAMP><BR></TD><TD>As <SAMP>fail()</SAMP><BR></TD></TR><TR VALIGN=top><TD><SAMP>operator void*()</SAMP><BR></TD><TD>Null pointer if <SAMP>fail()</SAMP> and non-null value otherwise<BR></TD></TR><TR VALIGN=top><TD><SAMP>iostate rdstate()</SAMP><BR></TD><TD>Value of stream state<BR></TD></TR></TABLE></CENTER><P>It is a good idea to check the stream state in some central place, for example:</P><PRE>if (!cout) error();</PRE><P>The state of <SAMP>cout</SAMP> is examined with <SAMP>operator!()</SAMP>, which will return <SAMP>true</SAMP> if the stream state indicates an error has occurred.</P><P>An ostream can also appear in a boolean position to be tested as follows:</P><PRE>if (cout << x) // okay!</PRE><P>The magic here is the <SAMP>operator void*()</SAMP> that returns a non-zero value when the stream state is non-zero.</P><P>Finally, the explicit member functions can also be used:</P><PRE>if (cout << x, cout.good()) // okay!;</PRE><P>Note that there is a difference between <SAMP>good()</SAMP> and <SAMP>operator!()</SAMP>. The function <SAMP>good()</SAMP> takes all flags into account; <SAMP>operator!()</SAMP> and <SAMP>fail()</SAMP> ignore <SAMP>eofbit</SAMP>.</P><A NAME="2.4.2"><H3>2.4.2 Catching Exceptions</H3></A><P>By default a stream does not throw any exceptions.<A HREF="endnote2.htm#fn23">[23]</A> You have to explicitly activate an exception because a stream contains <I>an exception mask</I>. Each flag in this mask corresponds to one of the error flags. For example, once the <SAMP>badbit</SAMP> flag is set in the exception mask, an exception will be thrown each time the <SAMP>badbit</SAMP> flag gets set in the stream state. The following code demonstrates how to activate an exception on an input stream <SAMP>InStr</SAMP>:</P><PRE>try { InStr.exceptions(ios_base::badbit | ios_base::failbit); \\1 in >> x; // do lots of other stream i/o}catch(ios_base::failure& exc) \\2{ cerr << exc.what() << endl; throw;}</PRE><TABLE CELLPADDING="3"><TR VALIGN="top"><TD>//1</TD><TD>In calling the <SAMP>exceptions()</SAMP> function, you indicate what flags in the stream's state shall cause an exception to be thrown.<A HREF="endnote2.htm#fn24">[24]</A></TD></TR><TR VALIGN="top"><TD>//2</TD><TD>Objects thrown by the stream's operations are of types derived from <SAMP>ios_base::failure</SAMP>. Hence this catch clause will catch all stream exceptions in principle. We qualify this generalization because a stream might fail to catch certain exceptions, e.g., <SAMP>bad_alloc</SAMP>, so that exceptions other than <SAMP>ios_base::failure</SAMP> might be raised. That's how exception handling in C+ works: you never know what exceptions will be raised.</TD></TR></TABLE><P>Generally, it is a good idea to activate the <SAMP>badbit</SAMP> exception and suppress the <SAMP>eofbit</SAMP> and <SAMP>failbit</SAMP> exceptions, because the latter do not represent exceptional states. A <SAMP>badbit</SAMP> situation, however, is likely to be a serious error condition similar to the memory shortage indicated by a <SAMP>bad_alloc</SAMP> exception. Unless you want to suppress exceptions thrown by iostreams altogether, we would recommend that you switch on the <SAMP>badbit</SAMP> exception and turn off <SAMP>eofbit</SAMP> and <SAMP>failbit</SAMP>.</P><HR><A HREF="for_5394.htm"><IMG SRC="images/prev.gif"></A> <A HREF="booktoc2.htm"><IMG SRC="images/toc.gif"></A><A HREF="fil_2309.htm"><IMG SRC="images/next.gif"></A><P>©Copyright 1996, Rogue Wave Software, Inc.</P></BODY></HTML>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?