尽管C不直接提供对错误处理(或异常处理)的支持,但是仍有多种方法可以在C中进行错误处理。程序员必须首先防止错误并测试函数的返回值。
许多C函数调用在出现错误的情况下都会返回-1或NULL,因此可以轻松地使用例如’if语句’对这些返回值进行快速测试。例如,在套接字编程中,将检查函数的返回值(例如socket(),listen()等),以查看是否存在错误。
示例:套接字编程中的错误处理
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
C语言中错误处理的不同方法
- 全局变量errno:在C中调用函数,将自动为名为errno的变量分配一个代码(值),该代码可用于识别遇到的错误的类型。它是一个全局变量,指示错误在任何函数调用期间发生,并且在头文件errno.h中定义。
errno的不同代码(值)表示不同类型的错误。以下是一些不同的errno值及其对应含义的列表:errno value Error 1 /* Operation not permitted */ 2 /* No such file or directory */ 3 /* No such process */ 4 /* Interrupted system call */ 5 /* I/O error */ 6 /* No such device or address */ 7 /* Argument list too long */ 8 /* Exec format error */ 9 /* Bad file number */ 10 /* No child processes */ 11 /* Try again */ 12 /* Out of memory */ 13 /* Permission denied */
// C implementation to see how errno value is // set in the case of any error in C #include
#include int main() { // If a file is opened which does not exist, // then it will be an error and corresponding // errno value will be set FILE * fp; // opening a file which does // not exist. fp = fopen("GeeksForGeeks.txt", "r"); printf(" Value of errno: %d\n ", errno); return 0; } 输出:
Value of errno: 2
注意:此处的errno设置为2,表示–没有此类文件或目录。在在线IDE上,它可能会显示错误13,表示权限被拒绝。
- perror()和strerror():上面获得的errno值指示遇到的错误的类型。
如果需要显示错误说明,则可以使用两个功能来显示与errorno相关的文本消息。这些功能是:- perror:它将显示您传递给它的字符串,然后显示一个冒号,一个空格,然后显示当前errno值的文本表示形式。
句法:void perror (const char *str) str: is a string containing a custom message to be printed before the error message itself.
- strerror():返回一个指向当前errno值的文本表示形式的指针。
句法:char *strerror (int errnum) errnum: is the error number (errno).
// C implementation to see how perror() and strerror() // functions are used to print the error messages. #include
#include #include int main () { FILE *fp; // If a file is opened which does not exist, // then it will be an error and corresponding // errno value will be set fp = fopen(" GeeksForGeeks.txt ", "r"); // opening a file which does // not exist. printf("Value of errno: %d\n ", errno); printf("The error message is : %s\n", strerror(errno)); perror("Message from perror"); return 0; } 输出:
在个人桌面上:Value of errno: 2 The error message is : No such file or directory Message from perror: No such file or directory
在在线IDE上:
Value of errno: 13 The error message is : Permission denied
注意:函数perror()显示传递给它的字符串,后跟冒号和当前errno值的文本消息。
- perror:它将显示您传递给它的字符串,然后显示一个冒号,一个空格,然后显示当前errno值的文本表示形式。
- 退出状态: C标准指定两个常量:EXIT_SUCCESS和EXIT_FAILURE,可以分别将其传递给exit()来指示成功或失败的终止。这些是在stdlib.h中定义的宏。
// C implementation which shows the // use of EXIT_SUCCESS and EXIT_FAILURE. #include
#include #include #include int main () { FILE * fp; fp = fopen ("filedoesnotexist.txt", "rb"); if (fp == NULL) { printf("Value of errno: %d\n", errno); printf("Error opening the file: %s\n", strerror(errno)); perror("Error printed by perror"); exit(EXIT_FAILURE); printf("I will not be printed\n"); } else { fclose (fp); exit(EXIT_SUCCESS); printf("I will not be printed\n"); } return 0; } 输出:
Value of errno: 2 Error opening the file: No such file or directory Error printed by perror: No such file or directory
- 除以零错误: C程序员常犯的一个陷阱是在除法命令之前不检查除数是否为零。零除会导致不确定的行为,没有C语言构造可以对此做任何事情。最好的选择是,首先检查分母,然后将其除以零。
// C program to check and rectify // divide by zero condition #include
#include void function(int); int main() { int x = 0; function(x); return 0; } void function(int x) { float fx; if (x==0) { printf("Division by Zero is not allowed"); fprintf(stderr, "Division by zero! Exiting...\n"); exit(EXIT_FAILURE); } else { fx = 10 / x; printf("f(x) is: %.5f", fx); } } 输出:
Division by Zero is not allowed
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。