Although C does not provide direct support to error handling (or exception handling), there are ways through which error handling can be done in C. A programmer has to prevent errors in the first place and test return values from the functions.
A lot of C function calls return -1 or NULL or set an in case of an error code as the global variable errno, so quick tests on these values are easily done with an instance of ‘if statement’.
What is errno?
errno is a global variable indicating the error occurred during any function call and it is defined inside <errno.h> header file.
When a function is called in C, a variable named errno is automatically assigned a code (value) which can be used to identify the type of error that has been encountered. Different codes (values) for errno mean different types of errors.
Below is a list of a few different errno values and their corresponding meaning:
errno value | Error |
1 | Operation not permitted |
2 | No such file or directory |
3 | No such process |
4 | Interrupted system call |
5 | I/O error |
6 | No such device or address |
7 | The argument list is too long |
8 | Exec format error |
9 | Bad file number |
10 | No child processes |
11 | Try again |
12 | Out of memory |
13 | Permission denied |
Example of errno
C
#include <errno.h>
#include <stdio.h>
int main()
{
FILE * fp;
fp = fopen ( "GeeksForGeeks.txt" , "r" );
printf ( "Value of errno: %d\n" , errno );
return 0;
}
|
Note: Here the errno is set to 2 which means “No such file or directory”. It may give Errno 13 in online IDE, which says permission denied.
Different Methods for Error Handling in C
Different methods are used to handle different kinds of errors in C. Some of the commonly used methods are:
- perror()
- strerr()
- ferror()
- feof()
- clearerr()
- Exit Status
- Divide by Zero Error
1. perror()
The perror() function is used to show the error description. It displays the string you pass to it, followed by a colon, a space, and then the textual representation of the current errno value.
Syntax
void perror(const char *str);
Parameters
- str: It is a string containing a custom message to be printed before the error message itself.
Example
C
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main()
{
FILE * fp;
fp = fopen ( " GeeksForGeeks.txt " , "r" );
printf ( "Value of errno: %d\n " , errno );
perror ( "Message from perror" );
return 0;
}
|
Output
Value of errno: 2
Message from perror: No such file or directory
2. strerror()
The strerror() function is also used to show the error description. This function returns a pointer to the textual representation of the current errno value.
Syntax
char *strerror(int errnum);
Parameters
- errnum: It is the error number (errno).
Example
C
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main()
{
FILE * fp;
fp = fopen ( " GeeksForGeeks.txt " , "r" );
printf ( "Value of errno: %d\n" , errno );
printf ( "The error message is : %s\n" , strerror ( errno ));
return 0;
}
|
OutputValue of errno: 2
The error message is : No such file or directory
3. ferror()
The ferror() function is used to check whether an error occurred during a file operation.
Syntax
int ferror(FILE *stream);
Parameters
- stream: It is the pointer that points to the FILE for which we want to check the error.
Return Value
- It returns a non-zero value if an error occurred, otherwise it returns 0.
Example
C
#include <stdio.h>
int main()
{
FILE * file = fopen ( "nonexistent_file.txt" , "r" );
if (file == NULL) {
perror ( "Error opening file" );
return 1;
}
int c;
while ((c = fgetc (file)) != EOF) {
}
if ( ferror (file)) {
printf (
"An error occurred while reading the file.\n" );
}
else {
printf ( "File read successfully.\n" );
}
fclose (file);
return 0;
}
|
Output
Error opening file: No such file or directory
4. feof()
The feof() function is used to check whether end-of-file indicator is set for a file steam.
Syntax
int feof(FILE *stream);
Parameters
- stream: It is the pointer that points to the FILE for which we want to check the error.
Return Value
- It returns a non-zero value if an error occurred, otherwise, it returns 0.
Example
C
#include <stdio.h>
int main()
{
FILE * fptr = fopen ( "filename.txt" , "r" );
if (fptr == NULL) {
perror ( "Error opening the file" );
return 1;
}
if ( ferror (fptr)) {
perror ( "Error occurred during file operations" );
}
fclose (fptr);
return 0;
}
|
Output
Error opening the file: No such file or directory
5. clearerr()
The clearerr() function is used to clear both end-of-file and error indicators for a file stream.
Syntax
void clearerr(FILE *stream);
Parameters
- stream: It is the pointer that points to the FILE for which we want to check the error.
Example
C
#include <stdio.h>
int main()
{
FILE * file = fopen ( "file.txt" , "r" );
if (file == NULL) {
perror ( "Error opening file" );
return 1;
}
if ( ferror (file)) {
printf ( "An error occurred while performing file "
"operations.\n" );
}
clearerr (file);
fclose (file);
return 0;
}
|
6. Exit Status
Exit status is the value returned by the program after its execution is completed which tells the status of the execution of the program.
The C standard specifies two constants: EXIT_SUCCESS and EXIT_FAILURE, that may be passed to exit() to indicate successful or unsuccessful termination, respectively. These are macros defined in <stdlib.h> header file.
Example
C
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE * fp;
fp = fopen ( "filedoesnotexist.txt" , "rb" );
if (fp == NULL) {
printf ( "Value of errno: %d\n" , errno );
printf ( "Error opening the file: %s\n" ,
strerror ( errno ));
perror ( "Error printed by perror" );
exit (EXIT_FAILURE);
printf ( "I will not be printed\n" );
}
else {
fclose (fp);
exit (EXIT_SUCCESS);
printf ( "I will not be printed\n" );
}
return 0;
}
|
Output
Value of errno: 2
Error opening the file: No such file or directory
Error printed by perror: No such file or directory
7. Divide by Zero Errors
A common pitfall made by C programmers is not checking if a divisor is zero before a division command. Division by zero leads to undefined behavior, there is no C language construct that can do anything about it. Your best bet is to not divide by zero in the first place, by checking the denominator.
Example
C
#include <stdio.h>
#include <stdlib.h>
void function( int );
int main()
{
int x = 0;
function(x);
return 0;
}
void function( int x)
{
float fx;
if (x == 0) {
printf ( "Division by Zero is not allowed" );
fprintf (stderr, "Division by zero! Exiting...\n" );
exit (EXIT_FAILURE);
}
else {
fx = 10 / x;
printf ( "f(x) is: %.5f" , fx);
}
}
|
Output
Division by zero! Exiting...
This article is contributed by MAZHAR IMAM KHAN. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.