Solved

How to use exceptions with streams?

Posted on 2004-10-18
10
225 Views
Last Modified: 2011-10-03
Hi experts,
I would like to use exception handling with streams.
I would like a try catch or if possible a mltiple catch:

ifstream in;
try
{
     open;
     do something with data;
}
catch(no file) {}
catch(eof){}
catch(whatever else){} //something like try ... catch .. catch .. default catch

1. I would like to catch all errors that could occur.
2. I would like to have different error handling for each error.
3. please don't use magic code like I did because I am missing
    the vocabluary for exception handling.

Thanks,
Jens
0
Comment
Question by:allmer
  • 4
  • 3
  • 3
10 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
Comment Utility
>>catch(no file) {}
>>catch(eof){}

That would require your ifstream implementation to throw errors on these conditions, which usually is not done. If you want to throw your own exceptions, that's however not too difficult:

ifstream in;

enum MyStreamError {

no_file,
eof
};

try
{
    in.open("somefile.sth");

    if (!in.is_open()) throw no_file;

    //...

    if (in.eof() throw eof;
}
catch (MyStreamError err)
{
    //...
}
0
 
LVL 1

Assisted Solution

by:gugario
gugario earned 250 total points
Comment Utility
After digging deep into the heart of the ifstream library, i found that there are 3 types of error flags which are set.
eofbit,
failbit,
and badbit.

eofbit is pretty simple, means that eof has been reached
failbit means error extracting from stream
badbit are all other errors

by checking badbit before failbit, you can assure that, if what you found is a failbit, then your error is that you couldn't open the file.

Here's an example:

#include <fstream>
using namespace std;

int main()
{
        ifstream in;
        in.exceptions ( ifstream::eofbit | ifstream::failbit | ifstream::badbit );
        try
        {
                in.open("nonexistentfile");
                 //do stuff
                in.close();
        }
        catch(ifstream::failure e) {
                if (in.eof())
                        cout << "end of file reached.\n";
                else if (in.bad())
                        cout << "unrecoverable error occurred.\n";
                else if (in.fail())
                        cout << "couldn't open file.\n";
        }

        return 1;
}

Gustavo
0
 
LVL 1

Expert Comment

by:gugario
Comment Utility
I like jkr's solution of  if (!in.is_open()) for testing for no file...  You can test for that when you catch, though... ifstream trhows the exception for you already when you try to use the >> operator.

if you want to take a look at the very unclear reference, you can go to this website:

http://www.cplusplus.com/ref/iostream/ios/exceptions.html

0
 
LVL 5

Author Comment

by:allmer
Comment Utility
Hi,
I liked both answers.
I can no theoretically throw and catch errors.
Practically it doesn't work, yet.
+ is there a catchAllErrors() or something that I can use to catch all errors?

Practical problem:
compiling Gugarios solution with g++ did not work for me:
--[jallmer@adenine gpf]$ g++ *.cpp
--unixgpf.cpp: In function `int main(int, char **)':
--unixgpf.cpp:65: parse error before `e'
--unixgpf.cpp:72: confused by earlier errors, bailing out
I am also including:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <list>

using namespace std;

BTW: I am an absolute beginner with UNIX maybe I am doing something wrong on that level.

Any ideas?
Thanks,
Jens
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>is there a catchAllErrors() or something that I can use to catch all errors?

You'd use

catch(...)
{
}

The problem with that 'catch all' is that since you don't know the type of the exception being caught, you can tell very little but that some unspecified exception occured.

>>--unixgpf.cpp:65: parse error before `e'

Try

      catch(ios_base::failure e) {

instead of

      catch(ifstream::failure e) {
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 5

Author Comment

by:allmer
Comment Utility
Good point!
I wouldn't know the error which leaves me in the dark, still.
So catching individual errors makes more sense :)

The practical side still doesn't work whatever i use.
ifstream::failure
ios_base::failure
ios::failure
-->
...parse error before e.
or:
#include <ios_base>
#include <ios_base.h>
#include <ios>
#include <ios.h>
-->
...no such file

Either way the compilation fails :(
Best,
Jens
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Just gave it a quick check, and my STL implementatio has it in <xiosbase>

Try a

grep failure *

in your include directory.
0
 
LVL 5

Author Comment

by:allmer
Comment Utility
The gcc version on the system, I am working with, is v3
with iGCCv3 (gcc3, libgcc, gcc3-c++, libstdc++3, libstdc++3-devel) installed.
Does that information help in determining if I can use exceptions?

Anyway, the exceptions are not called in my ms vs .net, either.
Any ideas?
0
 
LVL 1

Expert Comment

by:gugario
Comment Utility
Well, either ios_base::failure e or ifstream::failure e should work...
i don't understand what's going on, but your compiler is not recognizing failure for some reason...
if i were you, I would try to do a global catch..

just do a

catch(...)
{
   if (! in.is_open()) cout << "file not open";
   else if (in.eos()) cout << "end of file";
   else if (in.fail()) cout << "read error";
}

it doesn't matter that you don't have the ios_base::failure in there, because you KNOW for sure that the exception being thrown has to do with the ifstream.... so you don't need to catch a specific exception

and you don't need to catch a specific exception to test in for errors either...

this should get you around your problem of not being able to use failure.

Good luck!

Gustavo.
0
 
LVL 5

Author Comment

by:allmer
Comment Utility
Hi,
I am doing the following at the moment:
    ifstream in;
    in.exceptions ( ifstream::eofbit | ifstream::failbit | ifstream::badbit );
    try
    {
            double doub = 0;
            cout << "opening" << endl;
            in.open("nonexistentfile",ios::in);
            in >> doub;
        in.close();
            cout << "file closed" << endl;
    }
    catch(...){
            cout << "catching" <<endl;
        if (in.eof())
                cout << "end of file reached.\n";
        else if (in.bad())
                cout << "unrecoverable error occurred.\n";
        else if (in.fail())
                cout << "couldn't open file.\n";
    }

The output is always:
opening
file closed

I guess jkr is right about throwing errors and ifstream.
Nonetheless thanks to you both I can now implement
errorhandling in my programs ;)

I don't know what's wrong with the g++ installation on the
server, but that shall not be my problem.
Thanks,
Jens
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now