C Error Handling โ Using errno, perror, and strerror Effectively
Introduction โ How Is Error Handling Done in C?
C programming uses a minimal but flexible error-handling model based on global variables and diagnostic functions. Since C lacks exceptions (like in C++ or Java), errors from standard library functions must be manually checked, interpreted, and reported using tools like errno, perror(), and strerror().
In this guide, youโll learn:
- How to detect and interpret runtime errors
- The role of
errno,perror(), andstrerror() - Real-world use cases and practical examples
- Best practices for robust and clear error reporting
What Is errno in C?
errno is a global integer variable defined in <errno.h> that gets set by many standard library functions when an error occurs. It holds an error code that you can convert into a human-readable string using strerror() or display using perror().
#include <errno.h>
#include <stdio.h>
#include <string.h>
Always check the functionโs return value before accessing errno.
Common Functions That Set errno
| Function | Fails When… |
|---|---|
fopen() | File doesnโt exist or cannot be opened |
malloc() | No memory available |
strtol() | Input not convertible to a number |
read()/write() | I/O failure |
perror() โ Print Descriptive Error Message
perror("message") prints the custom message, followed by a colon and system error description based on errno.
Example:
FILE *fp = fopen("nonexistent.txt", "r");
if (fp == NULL) {
perror("Error opening file");
}
Output:
Error opening file: No such file or directory
strerror() โ Get Error Message String
strerror(errno) returns a string corresponding to the current error code.
printf("Error: %s\n", strerror(errno));
This method is useful when you want custom formatting or logging.
Complete Example
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main() {
FILE *fp = fopen("missing.txt", "r");
if (fp == NULL) {
printf("errno = %d\n", errno);
perror("fopen failed");
printf("strerror: %s\n", strerror(errno));
}
return 0;
}
Real-World Use Cases
| Scenario | Function Used | Error Description |
|---|---|---|
| File not found | fopen() | ENOENT (No such file) |
| Disk full | fwrite() | ENOSPC (No space left) |
| Permission denied | open() | EACCES (Access denied) |
| Invalid input format | strtol() | EINVAL (Invalid arg) |
Best Practices & Tips
Best Practice:
Always check a functionโs return value before checking errno, as errno may hold a stale error code.
Tip:
Use errno, perror(), and strerror() in combination for flexible and developer-friendly error output.
Pitfall:
Never assume errno == 0 means successโmany functions only set errno on failure, and not all failures update it.
Summary โ Recap & Next Steps
C’s error handling model is simple but powerful when used properly. By using errno in tandem with perror() and strerror(), you can detect, diagnose, and report errors gracefully.
Key Takeaways:
- Use
errnoto capture error codes from failed functions - Use
perror()to print a system-generated message with context - Use
strerror(errno)to retrieve error message strings for logging - Always validate the return value before checking
errno
Real-World Relevance:
Crucial in file I/O, memory allocation, system calls, and robust C applications requiring detailed failure reporting.
Frequently Asked Questions (FAQ)
What is errno used for?
It holds the error code when a library/system call fails, helping identify what went wrong.
What does perror() do?
It prints a message followed by the textual representation of errno.
Should I reset errno before a function call?
Itโs not required but good practice in some cases to avoid checking a stale value.
What is the difference between perror() and strerror()?
perror() prints to stderr automatically.strerror() returns a message string that you can format and log manually.
Where is errno defined?
In the <errno.h> header.
Share Now :
