Display Errors and errno Messages Automagically

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.

Leave a Reply