Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Error with ifstream and exceptions

Reply
Thread Tools

Error with ifstream and exceptions

 
 
Juha Nieminen
Guest
Posts: n/a
 
      02-07-2011
Paul <(E-Mail Removed)> wrote:
> Yeah Exceptions can be thrown anytime.


I like how you first insult Ian, and then proceed in your next post to
give the exact same answer he did. Way to go.
 
Reply With Quote
 
 
 
 
Marco
Guest
Posts: n/a
 
      02-07-2011
On 2011-02-07 "Paul" <(E-Mail Removed)> wrote:

> Many code examples only use try block around the file.open part, so they
> only want to stop the program from crashing in the event of a file.open
> error.


That's exactly what I want. I tried (see my first post), but it didn't work.

> Removing "fileIn.exceptions ( ifstream::failbit | ifstream::badbit );"
> might solve your problem.


I also tried it. The following code doesn't throw an exception.


#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main() {
ifstream fileIn;
try {
fileIn.open( "not_existent" ); }
catch ( ... ) {
// This never gets output
cout << "Error."; }

string line;
// while loop works okay now
while ( getline( fileIn, line ) ) {
cout << line << endl; }

fileIn.close();
return 0;
}


> I would check a few online tutorials and examples , there loads of them
> about file streams. Choose the option that suits you best.


I did, but there are many solutions that are considered bad practice. I don't
know yet how to do it the right way. What I try seems a bit verbose to me.

The following does what I want (and is pretty short, too):

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main() {
ifstream fileIn;
fileIn.open( "not_existent" );
if ( !fileIn )
cout << "Error." << endl;

string line;
while ( getline( fileIn, line ) ) {
cout << line << endl; }

fileIn.close();
return 0;
}

But I've read that this is C-like, not C++ and I should better use exceptions
to handle non-existent files. That's what I tried.

I thought I'm overseeing the obvious, but I think I used the wrong approach.


Regards
Marco

 
Reply With Quote
 
 
 
 
Marco
Guest
Posts: n/a
 
      02-07-2011
On 2011-02-07 Jonathan Lee <(E-Mail Removed)> wrote:

> Hi Marco,
> as others have mentioned, an exception can be thrown anywhere. The
> purpose
> of the try/catch structure is to indicate where you are interested in
> responding to exceptions (try), and what you're going to do when one
> occurs
> (catch).
>
> In the example you posted, for instance, you respond to
> ifstream::failure
> exceptions by printing a message. All other exceptions are left
> unhandled
> by your code, and continue with the default behavior (stack
> unwinding).
>
> The reason you might do this is that some exceptions may be
> "expected".
> Or perhaps its better to say some exceptions can be recovered from.
> Like reading from a file might suddenly fail if the file were on a
> network
> and someone kicked out the network cable. When the file can't be read
> from,
> your program may be able to continue by simply printing a message to
> the
> user and quitting from operating on the file.
>
> On the other hand, if while reading from that file the OS runs out
> of
> memory, the program probably can't continue. So you don't catch it;
> you
> let the exception propagate until it terminates your program.


Thanks for the explanation. It helped me understanding better how exceptions
work.


Regards
Marco

 
Reply With Quote
 
Paul
Guest
Posts: n/a
 
      02-07-2011

"Marco" <(E-Mail Removed)> wrote in message
news:4d502ac7$0$7652$(E-Mail Removed)-online.net...
> On 2011-02-07 "Paul" <(E-Mail Removed)> wrote:
>
>> Many code examples only use try block around the file.open part, so they
>> only want to stop the program from crashing in the event of a file.open
>> error.

>
> That's exactly what I want. I tried (see my first post), but it didn't
> work.
>
>> Removing "fileIn.exceptions ( ifstream::failbit | ifstream::badbit );"
>> might solve your problem.

>
> I also tried it. The following code doesn't throw an exception.
>
>
> #include <iostream>
> #include <string>
> #include <fstream>
> using namespace std;
>
> int main() {
> ifstream fileIn;
> try {
> fileIn.open( "not_existent" ); }
> catch ( ... ) {
> // This never gets output
> cout << "Error."; }
>
> string line;
> // while loop works okay now
> while ( getline( fileIn, line ) ) {
> cout << line << endl; }
>
> fileIn.close();
> return 0;
> }
>
>
>> I would check a few online tutorials and examples , there loads of them
>> about file streams. Choose the option that suits you best.

>
> I did, but there are many solutions that are considered bad practice. I
> don't
> know yet how to do it the right way. What I try seems a bit verbose to me.
>
> The following does what I want (and is pretty short, too):
>
> #include <iostream>
> #include <string>
> #include <fstream>
> using namespace std;
>
> int main() {
> ifstream fileIn;
> fileIn.open( "not_existent" );
> if ( !fileIn )
> cout << "Error." << endl;
>
> string line;
> while ( getline( fileIn, line ) ) {
> cout << line << endl; }
>
> fileIn.close();
> return 0;
> }
>
> But I've read that this is C-like, not C++ and I should better use
> exceptions
> to handle non-existent files. That's what I tried.
>
> I thought I'm overseeing the obvious, but I think I used the wrong
> approach.
>
>

It depends on the purpose of the program, how critical it is and how much
control you want.
The problem with both your programs is that you check incase the file handle
is null , but you don't abort if it is.
If you use a simple 'if' statement then you should construct your code in
such a way that...
if(filehandle is good){ do stuff}
else{ output error and abort }

It depends on the purpose and how critical your program is. If you are just
creating small test porgrams then its fine to not bother with error checking
at all. I like to always wrap file ops in an if statement, even in trivial
programs, as I think its good practise. I'd actually put file ops inside a
function and do something like:
if(filehandle) { fileOpsFunction( filehandle); }
It keeps your main() function cleaner and easier to read. I put almost
everything in functions.

HTH


 
Reply With Quote
 
Marco
Guest
Posts: n/a
 
      02-07-2011
On 2011-02-07 "Paul" <(E-Mail Removed)> wrote:

> It depends on the purpose of the program, how critical it is and how much
> control you want.


I start writing C++ programs and I want to start with a good programming style
from the scratch.

> The problem with both your programs is that you check incase the file
> handle is null , but you don't abort if it is.


It's not a problem. For demonstration I removed everything that is not really
necessary to understand my problem. I abort if the file is not found in the
real program.

> If you use a simple 'if' statement then you should construct your code in
> such a way that...
> if(filehandle is good){ do stuff}
> else{ output error and abort }
>
> It depends on the purpose and how critical your program is. If you are just
> creating small test porgrams then its fine to not bother with error
> checking at all. I like to always wrap file ops in an if statement, even in
> trivial programs, as I think its good practise. I'd actually put file ops
> inside a function and do something like:
> if(filehandle) { fileOpsFunction( filehandle); }
> It keeps your main() function cleaner and easier to read. I put almost
> everything in functions.


It is included in a function. I just removed all unnecessary stuff to make the
code as easy as possible.

But one question is still open: Is it possible to do something like:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main() {
ifstream fileIn;
fileIn.exceptions ( ifstream::failbit | ifstream::badbit );
try {
fileIn.open( "file" ); }
catch ( ifstream::failure e ) {
cout << "Error."; }
fileIn.exceptions ( none ); // Switch exceptions off

string line;
while ( getline( fileIn, line ) ) {
cout << line << endl;
}
fileIn.close();
return 0;
}

I mean to switch the exceptions off again after having switched them on before
to avoid that the while loop is able to throw an exception?


Regards
Marco

 
Reply With Quote
 
Paul
Guest
Posts: n/a
 
      02-07-2011

"Marco" <(E-Mail Removed)> wrote in message
news:4d504a82$0$7657$(E-Mail Removed)-online.net...
> On 2011-02-07 "Paul" <(E-Mail Removed)> wrote:
>
>> It depends on the purpose of the program, how critical it is and how much
>> control you want.

>
> I start writing C++ programs and I want to start with a good programming
> style
> from the scratch.
>
>> The problem with both your programs is that you check incase the file
>> handle is null , but you don't abort if it is.

>
> It's not a problem. For demonstration I removed everything that is not
> really
> necessary to understand my problem. I abort if the file is not found in
> the
> real program.
>
>> If you use a simple 'if' statement then you should construct your code in
>> such a way that...
>> if(filehandle is good){ do stuff}
>> else{ output error and abort }
>>
>> It depends on the purpose and how critical your program is. If you are
>> just
>> creating small test porgrams then its fine to not bother with error
>> checking at all. I like to always wrap file ops in an if statement, even
>> in
>> trivial programs, as I think its good practise. I'd actually put file ops
>> inside a function and do something like:
>> if(filehandle) { fileOpsFunction( filehandle); }
>> It keeps your main() function cleaner and easier to read. I put almost
>> everything in functions.

>
> It is included in a function. I just removed all unnecessary stuff to make
> the
> code as easy as possible.
>
> But one question is still open: Is it possible to do something like:
>
> #include <iostream>
> #include <string>
> #include <fstream>
> using namespace std;
>
> int main() {
> ifstream fileIn;
> fileIn.exceptions ( ifstream::failbit | ifstream::badbit );
> try {
> fileIn.open( "file" ); }
> catch ( ifstream::failure e ) {
> cout << "Error."; }
> fileIn.exceptions ( none ); // Switch exceptions off
>
> string line;
> while ( getline( fileIn, line ) ) {
> cout << line << endl;
> }
> fileIn.close();
> return 0;
> }
>
> I mean to switch the exceptions off again after having switched them on
> before
> to avoid that the while loop is able to throw an exception?
>
>

I'm not sure I haven't used exception masking before. I think it can be
done. A quick web search suggests to me that :
"By default, stream objects have a goodbit exception mask, which means no
exceptions are thrown when any of the state flags is set."
ref: http://www.cplusplus.com/reference/i...os/exceptions/

I would try fileIn.exceptions( ifstream::goodbit);

And see it that helps.


 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      02-07-2011
Marco wrote:
> On 2011-02-07 "Paul" <(E-Mail Removed)> wrote:
>
>> It depends on the purpose of the program, how critical it is and
>> how much control you want.

>
> I start writing C++ programs and I want to start with a good
> programming style from the scratch.
>
>> The problem with both your programs is that you check incase the
>> file handle is null , but you don't abort if it is.

>
> It's not a problem. For demonstration I removed everything that is
> not really necessary to understand my problem. I abort if the file
> is not found in the real program.
>
>> If you use a simple 'if' statement then you should construct your
>> code in such a way that...
>> if(filehandle is good){ do stuff}
>> else{ output error and abort }
>>
>> It depends on the purpose and how critical your program is. If you
>> are just creating small test porgrams then its fine to not bother
>> with error checking at all. I like to always wrap file ops in an
>> if statement, even in trivial programs, as I think its good
>> practise. I'd actually put file ops inside a function and do
>> something like:
>> if(filehandle) { fileOpsFunction( filehandle); }
>> It keeps your main() function cleaner and easier to read. I put
>> almost everything in functions.

>
> It is included in a function. I just removed all unnecessary stuff
> to make the code as easy as possible.
>
> But one question is still open: Is it possible to do something like:
>
> #include <iostream>
> #include <string>
> #include <fstream>
> using namespace std;
>
> int main() {
> ifstream fileIn;
> fileIn.exceptions ( ifstream::failbit | ifstream::badbit );
> try {
> fileIn.open( "file" ); }
> catch ( ifstream::failure e ) {
> cout << "Error."; }
> fileIn.exceptions ( none ); // Switch exceptions off
>
> string line;
> while ( getline( fileIn, line ) ) {
> cout << line << endl;
> }
> fileIn.close();
> return 0;
> }
>
> I mean to switch the exceptions off again after having switched
> them on before to avoid that the while loop is able to throw an
> exception?
>


But here the open() functions is not likely to throw any exceptions of
the kind you try to catch. Open() returns NULL if it cannot open the
file (which is not considered exceptional).

The only exception I would expect is std::bad_alloc if you are totally
out of memory. In that case, writing to std::cout is likely not to
work either (perhaps causing another bad_alloc).



Bo Persson




 
Reply With Quote
 
Marco
Guest
Posts: n/a
 
      02-07-2011
On 2011-02-07 "Paul" <(E-Mail Removed)> wrote:

> > I mean to switch the exceptions off again after having switched them on
> > before
> > to avoid that the while loop is able to throw an exception?
> >
> >

> I'm not sure I haven't used exception masking before. I think it can be
> done. A quick web search suggests to me that :
> "By default, stream objects have a goodbit exception mask, which means no
> exceptions are thrown when any of the state flags is set."
> ref: http://www.cplusplus.com/reference/i...os/exceptions/
>
> I would try fileIn.exceptions( ifstream::goodbit);


Thanks. That's the solution. It works.


Regards
Marco

 
Reply With Quote
 
Marco
Guest
Posts: n/a
 
      02-07-2011
On 2011-02-07 "Bo Persson" <(E-Mail Removed)> wrote:

> But here the open() functions is not likely to throw any exceptions of
> the kind you try to catch.


Yes, it is.

> Open() returns NULL if it cannot open the file (which is not considered
> exceptional).


open() is defined as:

void open ( const char * filename, ios_base:penmode mode = ios_base::in );

and it will never return NULL, if I'm not mistaken. One can check the ifstream
after open() as I suggested in an earlier post.


Regards
Marco

 
Reply With Quote
 
Joshua Maurice
Guest
Posts: n/a
 
      02-07-2011
On Feb 7, 4:57*am, Marco <(E-Mail Removed)> wrote:
> On 2011-02-07 "Paul" <(E-Mail Removed)> wrote:
>
>
>
> > >> Why does it throw an exception?

>
> > > You told it to.

>
> > >> The while block is outside of the try block.

>
> > > That isn't relevant, exceptions can be thrown anywhere.

>
> > Ian Collins obviously doesn't know how to answer the question properly.
> > I don't know how to answer the question but I know enough to get by.
> > Ian is different from most of the other arseholes around here because he is
> > obviously the most clueless of them all.

>
> > >> Sorry, maybe this is a stupid question, I'm a beginner in C++. But I
> > >> expected
> > >> exceptions only to be thrown in the try block. What else is it for?

>
> > > To catch exceptions thrown within it.

>
> > Ian obvioulsy gets confused between the try block and the catch block.

>
> I'm confused, too. Exceptions can be thrown everywhere, is that right? But
> what is the purpose of the try block? Why isn't it enough to write a catch
> block if the exceptions can be thrown in the try block and outside the try
> block? (I know it's not valid to write catch without try, it's just to
> understand how things work.)


Contrary to the other posters in this thread, C++ exceptions cannot be
thrown from anywhere.

In short, a C++ exception can only result from an executed "throw"
statement or or a failed dynamic_cast<reference_type>. (IIRC, those
are the only two things.)

C++ exceptions can also be thrown from standard library functions and
classes, such as std::vector, and from language features, such as the
new operator. However, these are likely implemented using "throw"
statements, and that's the better way to think about it. (Yes yes. I
know they don't have to be. Standard library functions and features
can be implemented whatever silly way they want. That's why I
specifically called them out.)

In practice, because of the widespread use of such features, it's
almost as if exceptions can come from anywhere, but C++ exceptions are
synchronous - they only come from a very specific set of things which
can throw.

If you want to talk about asynchronous exceptions, or exceptions from
null pointer accesses (such as what Visual Studios did by default in
older versions), then you're no longer talking about standard C++, and
you ought to consult those newsgroups and those documents instead.

Now, on to your question. Consider the code:

#include <iostream>
using namespace std;
int main()
{ try
{ try
{ throw 1;
}catch (... )
{ cout << 2 << endl;
throw 3;
}
}catch (... )
{ cout << 4 << endl;
}
throw 5;
}

Every catch block has exactly one associated try block. The reason is
that the catch block will only be invoked on exceptions thrown from
within that try block. For example, in the above code, throw 1 will
throw an exception from within a try block. That try block has an
associated catch block which matches the thrown exception (... matches
all exceptions), so that catch block will be executed. 2 is printed.
That catch block during execution executes another throw statement,
throw 3, which will throw a new exception. That new exception is
inside a different try block with an associated matching catch block,
so that associated catch block will be executed. 4 is printed.
Finally, control flows past the end of that catch block, and it hits
the throw 5 statement. This throw is outside of any try block, so it
is not caught, and so the program dies.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Exceptions - How do you make it work like built-in exceptions? Lie Python 3 01-14-2008 06:45 PM
Exceptions + Performance on path without exceptions gratch06@gmail.com C++ 3 04-16-2007 08:52 PM
Checked exceptions vs unchecked exceptions Ahmed Moustafa Java 5 07-14-2004 01:46 PM
Custom exceptions -- inherit from exceptions.Exception? Paul Miller Python 3 11-12-2003 09:24 AM
error passing ifstream. why? Giulio C++ 2 06-24-2003 09:19 PM



Advertisments