When to use "perror" and "fprintf"

L

L. Westmeier

Reading the man pages and some code did not really help me in
understanding the difference between - or better when I should use -
perror("...") and fprintf(stderr, "...")

Any hint or help is appreciated.

L. Westmeier
 
R

Richard Bos

L. Westmeier said:
Reading the man pages and some code did not really help me in
understanding the difference between - or better when I should use -
perror("...") and fprintf(stderr, "...")

They do rather different things. You use perror() to print a message to
stderr that corresponds to errno. You use fprintf() to print _anything_
to stderr, or any other stream.
perror() is a very specialised printing function;

perror(str);

is equivalent to

if (str)
fprintf(stderr, "%s: %s\n", str, strerror(errno));
else
fprintf(stderr, "%s\n", strerror(errno));

Richard
 
D

Darrell Grainger

Reading the man pages and some code did not really help me in
understanding the difference between - or better when I should use -
perror("...") and fprintf(stderr, "...")

The perror function works differently depending on the value of errno. If
you use a function that effects errno then it makes sense to use perror.
If you use a function that does not effect errno and simply returns an
error code you should use fprintf(stderr, fmt, ...).

For example, strtol will return LONG_MAX or LONG_MIN if a string is out of
range and set errno to ERANGE. So if strtol fails due to out of range, I
would use perror.
 
L

Lars Wirzenius

Darrell Grainger said:
For example, strtol will return LONG_MAX or LONG_MIN if a string is out of
range and set errno to ERANGE. So if strtol fails due to out of range, I
would use perror.

I have found that it is useful, in practice, to include the value of
errno in the output. These days, the error message output by perror
is often translated. This is good for the user, as they get an error
in a language they understand, but bad for me, if it is in a language
I do not understand. Therefore, I tend not to use perror and instead
use something like this:

fprintf(stderr, "Error: Can't open file: %d: %s\n",
errno, strerror(errno));

If there is an error, I can look up the reason using the numerical
error code regardless of what the text looks like.

(If I wanted to be really friendly towards the user, I'd use gettext
or a similar package to translate the format string into their preferred
language. I'll elide that in the interest of brevity.)
 
K

Karthik

L. Westmeier said:
Reading the man pages and some code did not really help me in
understanding the difference between - or better when I should use -
perror("...") and fprintf(stderr, "...")

Any hint or help is appreciated.

L. Westmeier
They are entirely different things. No need for confusion whatsoever.

fprintf - can be used to print to any stream.

perror - prints the error message string, if errno is set. (Usually
best done after a sys. call ).

For eg, if you fail to open a directory using fopen , errno is set to
EISDIR say.
sometimes it would make much more sense to print the corresponding
error message than playing with a macro like EISDIR (to the user, of
course !!).
 
D

Dan Pop

In said:
I have found that it is useful, in practice, to include the value of
errno in the output. These days, the error message output by perror
is often translated. This is good for the user, as they get an error
in a language they understand, but bad for me, if it is in a language
I do not understand. Therefore, I tend not to use perror and instead
use something like this:

fprintf(stderr, "Error: Can't open file: %d: %s\n",
errno, strerror(errno));

If there is an error, I can look up the reason using the numerical
error code regardless of what the text looks like.

This doesn't work for portable code, as the user's implementation need not
use the same errno codes as yours. Call strerror(errno) twice, once in
the user's locale, the other time in the "C" locale and compare the
two strings. If they're identical, display only one, otherwise display
both and ask the user to quote the English one verbatim.

Dan
 
O

OSHIMA

HI,

I use the function 'fprintf' to show the 'Usage' message.
if(argc != 2){
fprintf(stderr, "Usage: %s [filename]\n", argv[0]);
exit(1);
}
perror() cannot do that.

When I have to show the standard error message and
more information, fprintf() is very useful for me!
 

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

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top