Error handling (errno, perror)
Lesson 8.3: Error Handling with errno and perror
Robust programs are not just about getting things right; they're also about gracefully handling things when they go wrong. In C, error handling revolves around the errno variable and the perror function, which help you detect and report errors during file operations and other system calls.
Understanding errno
Global Error Indicator: errno is a special global variable defined in the errno.h header file. It holds an integer code representing the most recent error that occurred during a function call.
Error Codes: Each type of error has a unique numeric code. For example:
EPERM: Operation not permitted (e.g., trying to open a file you don't have permission for).
ENOENT: No such file or directory.
EINTR: Interrupted system call.
... (Many more error codes exist)
Checking errno: After calling a function that might fail, you should check the value of errno. If it's not zero, an error occurred.
The perror() Function
Printing Error Messages: The perror() function takes a string (usually a custom message) and prints it to the standard error stream (stderr), followed by a colon, a space, and then the textual representation of the current errno value.
Helpful for Debugging: This provides a user-friendly description of the error, aiding in troubleshooting.
Error Handling Workflow
Call a Function: Call a function that might fail (e.g., fopen, fread, fwrite).
Check the Return Value: Many functions return specific values to indicate success or failure (e.g., NULL for fopen if the file can't be opened).
Check errno (if necessary): If the return value indicates an error, examine errno to get a more specific error code.
Handle the Error: Take appropriate action based on the error code (e.g., print an error message, retry the operation, terminate the program).
Clear errno (Optional): If you plan to call other functions that might set errno, it's good practice to clear errno to 0 before proceeding.
Example: Error Handling with File Opening
C
#include <stdio.h>
#include <stdlib.h> // For exit()
#include <errno.h> // For errno
int main() {
FILE *fp = fopen("nonexistent_file.txt", "r");
if (fp == NULL) { // Error occurred while opening the file
perror("Error opening file");
exit(1); // Exit with error code 1
}
// ... (rest of your file processing code)
fclose(fp);
return 0;
}
Output (if the file doesn't exist):
Error opening file: No such file or directory
Key Points
errno: Global variable holding the error code of the most recent error.
perror(): Prints a user-friendly error message based on errno.
Always Check Return Values: Many functions signal errors through their return values.
Handle Errors Gracefully: Don't let your program crash unexpectedly; provide helpful error messages to the user.
strerror() (Advanced): This function returns a string representation of the error message corresponding to a given errno value.
Remember: Robust error handling is essential for building reliable software. By understanding and utilizing errno and perror, you're taking a crucial step towards becoming a proficient C programmer.