Error Handling in C
Error handling in C typically involves identifying and addressing runtime errors that can occur during program execution.

Error handling in C is an essential aspect of writing robust and reliable programs. It involves identifying and addressing errors, exceptions, and unexpected situations that may occur during program execution. In this tutorial, we will cover the basics of error handling in C, including common techniques and examples.
1. Introduction to Error Handling
Error handling in C typically involves identifying and addressing runtime errors that can occur during program execution. These errors can include issues like invalid input, file not found, memory allocation failures, and more. Proper error handling helps your program gracefully handle such errors and provide meaningful feedback to users.
2. Return Values for Error Handling
In C, many functions return special values to indicate errors. A common convention is to return -1
or NULL
to indicate failure and a non-negative value or a valid pointer to indicate success. For functions returning more detailed error information, you might see 0
indicating success and non-zero values indicating various error conditions.
3. errno
and perror
C provides the errno
variable, defined in the <errno.h>
header, to store error codes when functions encounter errors. You can use the perror
function to print a human-readable error message based on the value of errno
.
Here's an example:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main() {
FILE *file = fopen("nonexistent.txt", "r");
if (file == NULL) {
perror("Error");
fprintf(stderr, "Error code: %d\n", errno);
exit(EXIT_FAILURE);
}
// ... rest of the code to work with the file ...
fclose(file);
return 0;
}
In this example, we attempt to open a non-existent file. If fopen
fails, it sets errno
, and perror
is used to print an error message to the standard error stream.
4. Custom Error Handling with errno
You can also use errno
to implement custom error handling. You can set errno
to indicate specific error conditions, and then check it in your code to take appropriate action.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main() {
int result = performOperation();
if (result == -1) {
fprintf(stderr, "An error occurred: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// ... rest of the code ...
return 0;
}
In this example, performOperation
is a hypothetical function that returns -1
on error. We check the return value and, if an error occurs, use strerror(errno)
to get a string representation of the error.
5. Example: Handling File I/O Errors
Here's an example demonstrating error handling during file I/O operations:
#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
perror("Error opening file");
return 1; // Exit with an error code
}
// File operations go here
fclose(file);
return 0;
}
6. Example: Handling Memory Allocation Errors
Error handling is crucial when allocating memory dynamically with functions like malloc
. Here's an example:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = malloc(10 * sizeof(int));
if (arr == NULL) {
fprintf(stderr, "Memory allocation failed\n");
return 1; // Exit with an error code
}
// Memory operations go here
free(arr); // Don't forget to release allocated memory
return 0;
}
7. Exception Handling in C++ vs. Error Handling in C
In C++, error handling is often done using exception handling mechanisms like try
, catch
, and throw
, which provide more structured and flexible error handling. In contrast, C relies on return values and errno
for error handling, which can be less expressive and more manual.
In conclusion, error handling is an essential aspect of writing robust C programs. Understanding error codes, using errno
, and providing informative error messages are crucial for debugging and user-friendly error reporting. Proper error handling helps your program gracefully handle failures and ensures it behaves predictably in various situations.