Last week’s Lesson discussed the errno
variable and how it can display more detailed error messages. I have two updates to that Lesson.
The first is that error messages are best directed to the stderr
device. It’s the ugly stepsister of the C language device constants, running a distant third to stdin
(standard input) and stdout
(standard output).
The reason for the stderr
(standard error output) device is to ensure that a program’s output isn’t redirected to another device. The output to stderr
is always sent to the console (the screen) regardless of what other I/O manipulation is taking place outside the program. Bottom line:
Always send error messages to the stderr
device.
Here’s the update to last week’s code example:
#include <stdio.h> #include <errno.h> int main() { int result; result = rename("this.txt","that.txt"); if( result != 0 ) { fprintf(stderr,"File renaming error: "); switch(errno) { case EPERM: fprintf(stderr,"Operation not permitted\n"); break; case ENOENT: case ENOFILE: fprintf(stderr,"File not found\n"); break; case EACCES: fprintf(stderr,"Permission denied\n"); break; case ENAMETOOLONG: fprintf(stderr,"Filename is too long\n"); break; default: fprintf(stderr,"Unknown error\n"); } return(1); } puts("File renamed"); return(0); }
The only modification is that all error-output functions were changed from printf() to fprintf() and the stderr
device was added to the function’s arguments. That ensures that error messages are output to the standard error device. On modern computers, that means the messages always appear on the terminal window.
The second update involves using a new function. That function handles the errno
error code lookup, error message generation, and output to the standard error device. The function is called perror(), which I pronounce Pierre.
The perror() function is defined in the stdio.h
header file. Its argument is a text string displayed to the standard error device. If an errno
value is generated, a specific error message appears after that text, followed by a newline (\n
).
Here is an update to the previous code example, but using the perror() function:
#include <stdio.h> int main() { int result; result = rename("this.txt","that.txt"); if( result != 0 ) { perror("File renaming error"); return(1); } puts("File renamed"); return(0); }
The code is much shorter, yet it does the same thing. Here is sample output when the this.txt
file doesn’t exist:
File renaming error: No such file or directory
The perror() function displays its text argument (no newline). That output is followed by a colon, space, and an error message with a newline.
The only sad news is that not every C language library implements the perror() function. If not, then you can use the fprintf() function to output to the stderr
device, then use the errno
variable to help dish up a specific error message.