In C language, error detection and handling are very important because C itself does not provide a built-in exception handling mechanism, such as the try-catch blocks in Java or Python. Therefore, error handling usually relies on programmers manually writing code to detect and respond to error conditions. Below are some common error detection and handling methods:
Return Value Checking
Most C library functions return a special value on failure, usually -1 or NULL. Programmers should check these return values and take appropriate action when an error is detected.
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
perror("Error opening file");
exit(EXIT_FAILURE);
}
// File operations...
fclose(file);
return 0;
}
Error Codes
In addition to return values, some functions also return error codes through parameters. For example, the popen() function can return a file pointer, but it may also return NULL and return the error code through the global variable errno.
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *pipe = popen("command arg1 arg2", "r");
if (pipe == NULL) {
perror("popen");
exit(EXIT_FAILURE);
}
// Pipeline operations...
pclose(pipe);
return 0;
}
errno Global Variable
errno is a global variable used to store the error number of the most recent system call or library function call. The strerror() function can be used to convert the error number into a human-readable string.
Example:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main() {
char *buf = malloc(10);
if (buf == NULL) {
fprintf(stderr, "Error: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
free(buf);
return 0;
}
Assertions
The assert() function can be used during the debugging phase to detect error conditions. If the parameter of the assert() function is false (i.e., 0), the program will terminate and print an error message.
Example:
#include <assert.h>
#include <stdio.h>
int main() {
int value = 0;
assert(value != 0); // If value is 0, the program will terminate
return 0;
}
Non-Local Jumps
C language provides the setjmp() and longjmp() functions to implement non-local jumps, which can be used for error recovery. setjmp() saves information about the current execution environment, while longjmp() transfers control back to the save point of setjmp().
Example:
#include <stdio.h>
#include <setjmp.h>
jmp_buf env;
int main() {
if (setjmp(env) == 0) {
// Normal execution code
if (some_error_condition()) {
longjmp(env, 1); // Error occurred, jump back to setjmp point
}
} else {
// Error handling code
printf("Error occurred, recovering...\n");
}
return 0;
}
Logging
When an error is detected, recording detailed log information can help with subsequent error analysis and debugging.
Example:
#include <stdio.h>
#include <syslog.h>
int main() {
openlog("myapp", LOG_PID, LOG_DAEMON);
syslog(LOG_ERR, "An error occurred!");
closelog();
return 0;
}
User Feedback
In user-facing programs, providing clear error messages to users can help them understand what problem occurred and how to resolve it.
Example:
#include <stdio.h>
int main() {
if (!some_function()) {
printf("An error occurred. Please check your input and try again.\n");
}
return 0;
}



