Topic: Stream State
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/14 Raw View
stephen.clamage_nospam@eng.Sun.COM (Steve Clamage) writes:
|> > Can eof() and bad() ever both become set at the same time?
|>
|> Yes, as above. In addition, if you attempt some operations when eof()
|> is already true, the badbit gets set. I'm not going to list them here.
Can any one operation set both eof() and bad()? From what I've read in
the draft, I don't think so: ios::eofbit is normally only set when a
streambuf input function (sgetc, etc.) returns EOF, and ios::badbit when
one of these function returns via an exception (and so no return
value). I've not seen any cases where a single operation could set
both.
Furthermore, all extraction functions should start with the construction
of an istream::sentry object, and only precede if it is OK, which will
not be true if eof(). So once seen, eof() should inhibit any further
calls to the streambuf, at least for input.
Obviously, a user defined operator>> (or for that matter, any code)
could change any set of bits it wished, making both eof() and bad()
true, but if I understand correctly, this would really represent an
error in the user code. A correctly written operator>> must be of the
form:
istream&
operator>>( istream& input , MyType const& value )
{
try
{
istream::sentry s( input ) ;
if ( s )
{
// Do the conversion.
if ( formattingError )
input.clear( ios::failbit ) ;
// and NO further operations on the streambuf.
}
}
catch ( ... )
{
input.clear( ios::badbit ) ;
}
return input ;
}
Note that the constructor of s skips whitespace; if it encounters EOF
when doing so, it will test false, so we will only enter the if branch
if there is at least one non-white space character present to read.
I actually have several questions about this:
1. Globally, I'm not sure about the exception handling. My impression
is that if an exception is thrown by a function in the streambuf, either
when skipping blanks in the constructor of istream::sentry, or when
reading the actual data, this should translate to setting ios::badbit
(which in turn may trigger an exception). But what if MyType can also
throw -- shouldn't its exceptions propagate out unchanged? Does this
mean that I need separate try blocks for each operation that might
throw, since the handling must be different (and I cannot per se know
what types of exceptions might come from streambuf)?
2. Typically, I imagine that a formatting failure will be recognized
through reading a character that doesn't "fit". What if that character
is EOF? Should I also set ios::eofbit? My first take would be no:
I've encountered a formatting error, and I want the user to recognize it
as such, not as end of file. But what happens with e.g. EOF from a Unix
filebuf connected to a tty driver -- am I guaranteed by the filebuf that
the next read operation will also return EOF? (If so, then both Sun's
and g++'s implementations are broken:-). But since Unix doesn't really
define an EOF for a keyboard, but just something that sort of looks like
one, intermittently, perhaps it is the definition of Unix which is
broken.)
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]