C Tutorial – Error Handling (Exception Handling)
In this C language tutorial we are going to look at error handling. Although C programming does not provide direct support for error handling (also called exception handling), there are ways to do error handling.
Of course the programmer needs to prevent errors during coding and should always test the return values of functions called by the program. A lot of C function calls return a -1 or NULL in case of an error, so quick test on these return values are easily done with for instance an ‘if statement’.
In previous tutorials we already mention that this behavior (returning numbers to indicate an error) is also used in Unix or Linux like operating systems. For instance if a program successful ends the return value of the program is zero. If the program ends with an error usually a number larger than zero is returned (for example 1). (With command ‘echo $?’ on the command line you can display the return code of a program that has previously run).
So the one thing you need to remember is that you (the programmer) are responsible for error handling. You’re the person that needs to make sure that a program will gracefully terminate and not just CRASH unexpectedly! It is you that need to take appropriate action depending on the return values of function calls.
Global Variable errno
The global variable errno is used by C functions and this integer is set if there is an error during the function call. To make use of errno you need to include errno.h and you need to call ‘extern int errno;’
Let us take a look at an example:
#include <stdio.h>
#include <errno.h>
extern int errno;
int main () {
FILE * fp;
fp = fopen ("filedoesnotexist.txt", "rb");
if (fp == NULL) {
fprintf(stderr, "Value of errno: %d\n", errno);
} else {
fclose (fp);
}
return 0;
}
Note: that you should always use stderr file stream to output all of the errors
The output of the program will be something like:
Value of errno is: 2
As you can see we include the stdio.h and errno.h header files. Then ‘extern int errno’ is called, so we now have access to the integer errno. To generate an error we open a file that doesn’t exist. If the file pointer (fp) equals NULL then we print the value of errno (in this case errno will be 2). If we get a file pointer (in case the file exists) we close the file.
The functions strerror() and perror()
In the previous example the errno had a value of 2. But what is the meaning of the value of 2? How does the user know what this error is? Of course a good practice is to make some documentation where you describe each error number and what the user should do. But it is also a good practice to give a good descriptive error message when an error occurs in the program. The C programming language has two functions that can be used to display a text message that is associated with errno. The functions are strerror() and perror().
The function strerror() returns a pointer to the textual message of the current errno value. The function perror() displays a string you pass to it, followed by a colon and the textual message of the current errno value.
Before we look at an example it is important to note that you should always use stderr file stream to output all of the errors that may occur. Let’s take a look at an example:
#include <stdio.h>
#include <errno.h>
#include <string.h>
extern int errno;
int main () {
FILE * fp;
fp = fopen ("filedoesnotexist.txt", "rb");
if (fp == NULL) {
fprintf(stderr, "Value of errno: %d\n", errno);
fprintf(stderr, "Error opening the file: %s\n", strerror( errno ));
perror("Error printed by perror");
} else {
fclose (fp);
}
return 0;
}
Note: that the header file string.h is included, otherwise you get an segmentation fault when you use strerror() function in this program. (Try it! I tried it on Red Hat 6 system using gcc).
The output of the program will be:
Value of errno: 2
Error opening the file: No such file or directory
Error printed by perror: No such file or directory
As in the previous example we include some header files and call ‘extern int errno’, so we can use errno in our program. As before we open an non existing file and if the file pointer equals NULL we got an error. First we print the errno. Then we use strerror() function to give a message of our own and print the text representation of errno. Then perror() function is used to give a message of our own, followed by a colon and the textual representation of errno.
Program Exit Status
As previous mentioned it is a good practice to return a value if the program end successful or ends with an error. To do this we can use the macros EXIT_SUCCESS and EXIT_FAILURE that are defined in stdlib.h (so you need to include this header file in your program).
If we take a look in the stdlib.h file (on Linux) you will find something like this:
/* We define these the same for all machines.
Changes from this to the outside world should be done in `_exit'. */
#define EXIT_FAILURE 1 /* Failing exit status. */
#define EXIT_SUCCESS 0 /* Successful exit status. */
Let’s change our previous program by including the two exit macros:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
extern int errno;
int main () {
FILE * fp;
fp = fopen ("filedoesnotexist.txt", "rb");
if (fp == NULL) {
fprintf(stderr, "Value of errno: %d\n", errno);
fprintf(stderr, "Error opening the file: %s\n", strerror( errno ));
perror("Error printed by perror");
exit(EXIT_FAILURE);
} else {
fclose (fp);
exit(EXIT_SUCCESS);
}
return 0;
}
Let us compile the program on a Linux machine and too show the result and show you the return codes of the program:
# ./err
Value of errno: 2
Error opening the file: No such file or directory
Error printed by perror: No such file or directory
# echo $?
1
# touch filedoesnotexist.txt
# ./err
# echo $?
0
#
Note: with the ‘echo $?’ command on the command line you can display the return code of a program that has previously run.
With the ./err we run the program and we get the know messages of the error. We give an echo $? to display the return code, in this case a one which indicate an error has occurred. Then with the touch filedoesnotexist.txt command we create the file (that was previously missing). We start the program again and we get NO errors. Again we ask the return code and as you can see a zero is returned indicating that there was no error.
That’s all for this tutorial, may your errors be minor, but readable for all users by using the techniques described in this tutorial.
cool post
union structure
typedef union large_integer{
struct{
Dword lowpart;
long highpart;
};
struct{
Dword lowpart;
long highpart;
}u;
longlong quadpart;}
large_integer,*plarge_integer;