Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

C Error Handling

Error Handling in C

Unlike C++ or Java, C has no built-in exception mechanism. Error handling in C is done through:

  • Return values — functions return a special value (e.g., -1, NULL, 0) to signal failure.
  • errno — a global integer variable set by system calls and library functions when an error occurs.
  • perror() — prints a human-readable error message to stderr.
  • strerror() — returns the error message string for a given errno value.

Return Value Pattern

The most fundamental C error handling pattern: check the return value of every function that can fail.

Checking Return Values
#include <stdio.h>
#include <stdlib.h>

// Function returns -1 on error, result on success
int divide(int a, int b, int *result) {
    if (b == 0) {
        return -1;  // error code
    }
    *result = a / b;
    return 0;  // success
}

int main() {
    int result;

    // Success case
    if (divide(10, 2, &result) == 0) {
        printf("10 / 2 = %d\n", result);
    } else {
        printf("Error: division failed\n");
    }

    // Error case
    if (divide(10, 0, &result) == 0) {
        printf("10 / 0 = %d\n", result);
    } else {
        printf("Error: cannot divide by zero\n");
    }

    // malloc returns NULL on failure
    int *arr = (int*)malloc(1000000000 * sizeof(int));  // huge allocation
    if (arr == NULL) {
        fprintf(stderr, "Error: memory allocation failed\n");
        return EXIT_FAILURE;
    }
    free(arr);

    return EXIT_SUCCESS;
}

errno, perror() and strerror()

errno is set by system calls when they fail. Always check errno immediately after a failed call — the next function call may overwrite it.

errno CodeValueMeaning
ENOENT2No such file or directory
EACCES13Permission denied
ENOMEM12Out of memory
EINVAL22Invalid argument
ERANGE34Result out of range
errno, perror() and strerror()
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main() {
    // Try to open a file that doesn't exist
    FILE *fp = fopen("nonexistent.txt", "r");

    if (fp == NULL) {
        // errno is set by fopen on failure
        printf("errno value: %d\n", errno);

        // perror: prints "prefix: error message" to stderr
        perror("fopen failed");

        // strerror: returns the error string
        printf("Error: %s\n", strerror(errno));
    }

    // Reset errno before next call
    errno = 0;

    // Math error: log of negative number
    #include <math.h>
    double result = sqrt(-1.0);
    if (errno == EDOM) {
        perror("sqrt(-1)");  // sqrt(-1): Numerical argument out of domain
    }

    return 0;
}

/*
Output:
errno value: 2
fopen failed: No such file or directory
Error: No such file or directory
*/

Custom Error Handling Pattern

A clean pattern for larger programs: define your own error codes and a centralized error handler.

Custom Error Codes Pattern
#include <stdio.h>
#include <stdlib.h>

// Custom error codes
typedef enum {
    ERR_OK       = 0,
    ERR_NULL_PTR = 1,
    ERR_DIV_ZERO = 2,
    ERR_OVERFLOW = 3,
    ERR_IO       = 4
} ErrorCode;

// Error message lookup
const char* errorMessage(ErrorCode code) {
    switch (code) {
        case ERR_OK:       return "Success";
        case ERR_NULL_PTR: return "Null pointer";
        case ERR_DIV_ZERO: return "Division by zero";
        case ERR_OVERFLOW: return "Integer overflow";
        case ERR_IO:       return "I/O error";
        default:           return "Unknown error";
    }
}

// Function using custom error codes
ErrorCode safeDivide(int a, int b, int *out) {
    if (out == NULL) return ERR_NULL_PTR;
    if (b == 0)      return ERR_DIV_ZERO;
    *out = a / b;
    return ERR_OK;
}

int main() {
    int result;
    ErrorCode err;

    err = safeDivide(10, 2, &result);
    if (err == ERR_OK) printf("10/2 = %d\n", result);
    else printf("Error: %s\n", errorMessage(err));

    err = safeDivide(10, 0, &result);
    if (err == ERR_OK) printf("10/0 = %d\n", result);
    else printf("Error: %s\n", errorMessage(err));  // Error: Division by zero

    err = safeDivide(10, 2, NULL);
    if (err == ERR_OK) printf("result = %d\n", result);
    else printf("Error: %s\n", errorMessage(err));  // Error: Null pointer

    return 0;
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.