Error Handling
C does not provide direct support for error handling, but as a system programming language, it allows you to access underlying data through return values. When an error occurs, most C or UNIX function calls return 1 or NULL and set an error code errno, which is a global variable indicating an error during the function call. You can find various error codes in the errno.h header file.
Therefore, C programmers can check the return value and decide on the appropriate action based on the return value. Developers should set errno to 0 during program initialization, which is a good programming practice. A value of 0 indicates no errors in the program.
errno, perror(), and strerror()
C provides perror() and strerror() functions to display text messages related to errno.
- The perror() function displays the string you pass to it, followed by a colon, a space, and the textual representation of the current errno value.
- The strerror() function returns a pointer to the textual representation of the current errno value.
Let's simulate an error condition by trying to open a non-existent file. You can use multiple ways to output error messages, here we use functions to demonstrate usage. Also, note that you should use the stderr file stream for all error output.
Example
#include <stdio.h>
#include <errno.h>
#include <string.h>
extern int errno;
int main() {
FILE *pf;
int errnum;
pf = fopen("unexist.txt", "rb");
if (pf == NULL) {
errnum = errno;
fprintf(stderr, "Error Number: %d\n", errno);
perror("Error printed by perror");
fprintf(stderr, "Error opening file: %s\n", strerror(errnum));
} else {
fclose(pf);
}
return 0;
}
When the above code is compiled and executed, it produces the following result:
Error Number: 2
Error printed by perror: No such file or directory
Error opening file: No such file or directory
Division by Zero Error
When performing division, if you do not check if the divisor is zero, it will cause a runtime error.
To avoid this, the following code checks if the divisor is zero before performing the division:
Example
#include <stdio.h>
#include <stdlib.h>
int main() {
int dividend = 20;
int divisor = 0;
int quotient;
if (divisor == 0) {
fprintf(stderr, "Division by zero! Exiting...\n");
exit(-1);
}
quotient = dividend / divisor;
fprintf(stderr, "The value of quotient is: %d\n", quotient);
exit(0);
}
When the above code is compiled and executed, it produces the following result:
Division by zero! Exiting...
Program Exit Status
Normally, when a program successfully completes an operation and exits, it has the value EXIT_SUCCESS. Here, EXIT_SUCCESS is a macro defined as 0.
If there is an error condition in the program, when you exit, you have the status value EXIT_FAILURE, defined as -1. Therefore, the above program can be written as:
Example
#include <stdio.h>
#include <stdlib.h>
int main() {
int dividend = 20;
int divisor = 5;
int quotient;
if (divisor == 0) {
fprintf(stderr, "Division by zero! Exiting...\n");
exit(EXIT_FAILURE);
}
quotient = dividend / divisor;
fprintf(stderr, "The value of quotient is: %d\n", quotient);
exit(EXIT_SUCCESS);
}
When the above code is compiled and executed, it produces the following result:
The value of quotient is: 4