Thread View: comp.std.c++
2 messages
2 total messages
Started by Nico Josuttis
Mon, 18 Mar 1996 17:50
FOR comp.std.c++: problems with I/O exceptions
Author: Nico Josuttis
Date: Mon, 18 Mar 1996 17:50
Date: Mon, 18 Mar 1996 17:50
105 lines
4265 bytes
4265 bytes
Hi,
Trying the new feature of throwing stream exceptions
i wrote the following program:
------------------------ snip ----------------------
#include <iostream>
#include <cstdlib>
using namespace std;
/* process and print sum of integer read from cin
*/
int main()
{
cin.exceptions (ios::failbit | ios::badbit);
try {
int value, sum;
/* while not EOF
* read and add value
*/
sum = 0;
#ifdef VERSION1
while (cin >> ws) {
cin >> value;
#else
while (cin >> value) {
#endif
sum += value;
}
cout << "sum: " << sum << endl;
}
catch (ios::failure error) {
cerr << "Error: " << error.what() << endl;
exit (EXIT_FAILURE);
}
}
------------------------ snip ----------------------
But it didn't work as I expected, because also on EOF
I ALWAYS got the failbit exception!
And that happened in both versions.
After some investigation I found the problem and was surprised,
because the compiler and library I used had no bug.
Its a feature, which we should change IMHO.
The problem is, that istream::ipfx() always calls setstate(failbit),
if after any preparation good() is false.
So even if only the eofbit is set (due to the skip of whitespace),
the failbit is also set.
I think, therefore we must change the specification of ixpf()
to call setstate(eofbit) if eof() is true and setstate(failbit)
if any other problem occurs.
But even if that would be fixed, i would have problems implementing
a simple filter like:
char c;
while (cin.get(c)) {
cout.put(c);
}
With the actual specification i see no chance to get no exception on
EOF but an exception for any failure.
Therefore perhaps a deeper change in the specification would be
necessary, namely
- either don't set failbit if eofbit is set
- or set eofbit on eof and set the failbit with the NEXT try to read data
In general I need a chance to handle eof without getting
failbit exceptions.
ONE OTHER POINT I found:
You might say, that i could catch all exceptions and look at the
bits.
BUT i got no information about the reason for I/O exceptions.
I have only what() to get a
undefined message, but I think informations about the stream
or at least about the state of the stream would be senseful
to process exceptions on EOF different from other problems.
So for ios_base::failure an additional member like
state, which is rdstate() of the stream would be very senseful.
For example I'd like to open file and process its data until EOF
without any exception, but having exceptions for any error
and the information to handle it properly.
If for example i open 2 files i have no chance to check
which file got the problem.
Please correct me if I'am wrong or don't see any simple solution.
--------
Nico address: BREDEX GmbH
email: nico@bredex.de Nicolai Josuttis
Fallersleber-Tor-Wall 23
phone: +49 531 24330-0 D-38100 Braunschweig
fax: +49 531 24330-99 Germany
--------
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Re: FOR comp.std.c++: problems with I/O except
Author: Steve Clamage
Date: Tue, 19 Mar 1996 01:16
Date: Tue, 19 Mar 1996 01:16
91 lines
4148 bytes
4148 bytes
In article RAA08990@bredex.bredex.de, Nico Josuttis <nico@bredex.de> writes:
>Hi,
>Trying the new feature of throwing stream exceptions
>i wrote the following program:
[ trimmmed ]
> try {
> int value, sum;
>
> /* while not EOF
> * read and add value
> */
> sum = 0;
> while (cin >> value) {
> sum += value;
> }
>
> cout << "sum: " << sum << endl;
>
> }
> catch (ios::failure error) {
> cerr << "Error: " << error.what() << endl;
> exit (EXIT_FAILURE);
> }
>But it didn't work as I expected, because also on EOF
>I ALWAYS got the failbit exception!
>The problem is, that istream::ipfx() always calls setstate(failbit),
>if after any preparation good() is false.
>So even if only the eofbit is set (due to the skip of whitespace),
>the failbit is also set.
That is the desired behavior, and your program should take it into account.
For example, suppose the file ends with whitespace (which it often will,
if only because of a final newline before the EOF). You attempt to read
an int value, whitespace is skipped, and EOF is reached before any
valid characters are found. That is a failure, by definition. The failure
cannot be predicted before starting the input, since characters are
available at the start. As it happens, you are not interested in any
of the characters which are available.
Now suppose that EOF is already true when starting the input. Again by
definition, input fails, since no characters are available for reading.
The ipfx() function is called as part of starting an input operation.
You are asking for input, and to be notified if the input fails. It fails
-- no input available -- and you are notified.
When you have a loop like
while( cin >> value ) { ... }
it will ALWAYS end by failing, since the loop only ends by finding improper
input or reading past EOF, and reading past EOF is a failure. Thus,
you probably do not want to use an exception to detect the end of the
loop.
> ... In general I need a chance to handle eof without getting
>failbit exceptions.
I think it is more likely that you don't want to throw an exception on
failure unless failure is not expected to happen. When reading input up
to the end, failure will always occur. A schema like the following
gives you the control you want without using exceptions:
while( cin >> value ) {
... do something with value
}
if( cin.eof() ) ... no more input available
else ... error in input
More likely, you would write a single test like this:
if( ! cin.eof() ) ... error in input
Exceptions are best used for those cases where you don't expect
them to be triggered, and you need to escape to a higher level in the
program when they do occur. Exceptions give you a way to escape without
having to pass error status explicitly through a chain of function calls.
Don't use exceptions for normal loop control; they are inefficient for
that purpose and cause you to write more complicated code instead of
less complicated code.
---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ 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 ]
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads