Solved

How to use exceptions with streams?

Posted on 2004-10-18
10
239 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
ID: 12339865
>>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
ID: 12340120
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
ID: 12340150
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
ID: 12340852
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
ID: 12341499
>>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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 5

Author Comment

by:allmer
ID: 12341640
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
ID: 12341737
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
ID: 12342387
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
ID: 12343524
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
ID: 12351660
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

867 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

17 Experts available now in Live!

Get 1:1 Help Now