C - Error Handling
C doesn’t have exceptions; use return codes, errno, and defensive checks to handle errors.
Learning Objectives
- Check return values and use errno with perror/strerror.
- Perform robust input validation and resource cleanup.
Return codes and errno
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(void) {
  FILE *fp = fopen("missing.txt", "r");
  if (!fp) {
    perror("fopen failed");          // prints reason based on errno
    fprintf(stderr, "error: %s\n", strerror(errno));
    return 1;
  }
  fclose(fp);
}
Validation and cleanup
#include <stdio.h>
#include <stdlib.h>
int process(const char *path) {
  FILE *fp = fopen(path, "r");
  if (!fp) return -1;
  char *buf = malloc(1024);
  if (!buf) { fclose(fp); return -2; }
  // ... use fp and buf ...
  free(buf); fclose(fp); return 0;
}
Common Pitfalls
- Ignoring function return values.
- Using uninitialized memory or freed pointers after an error.
- Leaking resources when taking early returns.