Getting Error Text from ifstream

J

Johannes Bauer

Hello group,

coming from C, I'm used to somthing like this when opening a file

const char *foobar = "this.txt";
FILE *f;
f = fopen(foobar, "r");
if (!f) {
fprintf(stderr, "Couldn't open %s: %s\n", foobar, strerror(errno));
exit(EXIT_FAILURE);
}

translating that somewhat to C++ yields me with

const char *foobar = "this.txt";
std::ifstream f(foobar);
if (!f) {
throw GenericException("Couldn't open file.");
}

So I can detect that opening the file wasn't successful, but I don't
know *why* (i.e. permissions, no such file or directory, etc.). My guess
is that strerror and errno still do what I expect them to do, however I
think that would be a very C-way to solve things.

How can I accomplish strerror(errno) on the std::ifstream with C++ means?

Greetings,
Johannes
 
D

David Harmon

On Tue, 20 Nov 2007 14:45:24 +0100 in comp.lang.c++, Johannes Bauer
So I can detect that opening the file wasn't successful, but I don't
know *why* (i.e. permissions, no such file or directory, etc.). My guess
is that strerror and errno still do what I expect them to do, however I
think that would be a very C-way to solve things.

Use strerror(), perror(), and errno and consider yourself lucky. The
C++ standard doesn't exactly promise that they will work for iostreams,
but they do for the compilers I use. That's the best you get for now.
 
J

Johannes Bauer

David said:
Use strerror(), perror(), and errno and consider yourself lucky. The
C++ standard doesn't exactly promise that they will work for iostreams,
but they do for the compilers I use. That's the best you get for now.

Oh, that's really a shame. Is anything planned about this in future
specifications?

Greetings,
Johannes
 
D

David Harmon

Use strerror(), perror(), and errno and consider yourself lucky. The
C++ standard doesn't exactly promise that they will work for iostreams,
but they do for the compilers I use. That's the best you get for now.

Oh, that's really a shame. Is anything planned about this in future
specifications?[/QUOTE]

I have not heard of any. That would be a good question for
comp.std.c++, where the c++ standardization process is discussed.
 
J

James Kanze

coming from C, I'm used to somthing like this when opening a file
const char *foobar = "this.txt";
FILE *f;
f = fopen(foobar, "r");
if (!f) {
fprintf(stderr, "Couldn't open %s: %s\n", foobar, strerror(errno));
exit(EXIT_FAILURE);
}
translating that somewhat to C++ yields me with
const char *foobar = "this.txt";
std::ifstream f(foobar);
if (!f) {
throw GenericException("Couldn't open file.");
}
So I can detect that opening the file wasn't successful, but I
don't know *why* (i.e. permissions, no such file or directory,
etc.). My guess is that strerror and errno still do what I
expect them to do, however I think that would be a very C-way
to solve things.

It's not really a C way either, since C doesn't say anything
about the state of errno after a failed fopen.

Pragmatically, it's what I do as well.
How can I accomplish strerror(errno) on the std::ifstream with
C++ means?

You can't associate errno with an std::ifstream anymore than you
can associate it a FILE*.
 
J

Johannes Bauer

James said:
It's not really a C way either, since C doesn't say anything
about the state of errno after a failed fopen.

Pragmatically, it's what I do as well.

Does it really not? My Linux manpage says its fopen implementation is in
accordance with ANSI C3.159-1989 ("ANSI C") and errno (according to
another manpage) seems to appear in the ISO-C standard - yet the
connection of the two is purely a Linux thing and could break on any
other system?
You can't associate errno with an std::ifstream anymore than you
can associate it a FILE*.

This is really a lack, as I think the language should provide means for
that. Many are, in fact, operating system independent after all.

Greetings,
Johannes
 
J

James Kanze

James Kanze schrieb:
Does it really not? My Linux manpage says its fopen
implementation is in accordance with ANSI C3.159-1989 ("ANSI
C") and errno (according to another manpage) seems to appear
in the ISO-C standard - yet the connection of the two is
purely a Linux thing and could break on any other system?

In theory. All ISO 9899 says is that "If the open operation
fails, fopen returns a null pointer." In addition, look at the
possible values for errno on the Linux (or any other Unix
system) man page: the only values defined by the C standard are
EDOM, EILSEQ and ERANGE. (I'm pretty sure that Posix requires a
good deal more.)

In practice, errno was put into the C standard for a reason.
The C standard also clearly says (concerning errno.h):
"Additional macro definitions, beginning with E and a digit or E
and an uppercase letter, may also be specified by the
implementation." It also says: "The value of errno is zero at
program startup, but is never set to zero by any library
function. The value of errno may be set to nonzero by a library
function call whether or not there is an error, provided the use
of errno is not documented in the description of the function in
this International Standard." From a QoI point of view, I
expect errno to be set to something significant in case of an
error---that's what it's there for. (I don't count on it not
being set in the absense of an error. I can't think of a good
example from the standard, but imagine a function like
gethostname(), which uses several different strategies. Some of
which may have failed and set errno before the function finally
finds one which works.)

The problem in C++, of course, is that this is all
implementation dependent, and the implementation (Linux, Posix,
etc.) only documents the C functions. Again, in practice,
neither fopen nor filebuf::eek:pen actually set errno themselves.
Both of them ultimately call the Posix function open(), and the
Posix function open() does set errno in case of an error. And
I'd be very surprised (and disappointed) that an implementation
then modified it if open() failed.
This is really a lack, as I think the language should provide
means for that. Many are, in fact, operating system
independent after all.

And others aren't. Only defining some, but leaving the
implementation free to use others as well, doesn't buy you much.

It would make sense if the standard said something to the effect
that in case of failure, errno would be set to an implementation
defined non-zero value, depending on the cause of the failure.
But I wouldn't worry about it too much, since that's the obvious
intention, and what all implementations do anyway. Far more
important would be cleaning up the error handling in general, so
that e.g. you could reliably distinguish between a hardware read
error, an error in the format, and the end of file.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top