婚纱摄影网站建设方案,微博wordpress插件,网站文章做排名,广告优化师工作内容目录
前言
错误号处理方式
errno.h头文件
error.h头文件
参数解释#xff1a;
关于的”__attribute__“解释#xff1a;
关于“属性”的解释#xff1a;
实例一#xff1a;
实例二#xff1a;
error.h与errno.h的区别
补充内容#xff1a; 前言
在开始学习…目录
前言
错误号处理方式
errno.h头文件
error.h头文件
参数解释
关于的”__attribute__“解释
关于“属性”的解释
实例一
实例二
error.h与errno.h的区别
补充内容 前言
在开始学习之前先向各位推荐c和c指令手册的官方网站C语言|C中文网 (c-cpp.com) 其次关于C语言的错误处理一共分为三个部分错误号处理方式、断言处理方式、信号处理方式非局部跳转处理方式我们将这四部分分为四篇文章来写......
错误号处理方式
errno.h头文件
文件说明是一个标准C库头文件
概念标准库中的一些函数通过向errno.h中声明的整形全局变量errno存储一个错误码1、2、3等数字来表示有错误发生大部分使用errno变量的函数集中在math.h中但也有一些在标准库的其他部分并定义了一组与错误码相关的宏EACCES、EINVAL、ENOMEM 等
//由于是宏定义所以将EACCES等宏存储至errno中时就相当于将这些宏所对应的错误码数字存放在errno中
#define EACCES 数字
功能检查调用标准库中函数的操作是否成功
简述运行过程
1、当我们要调用一个库函数该库函数不论是正常运行还是非正常运行都会在最后给errno变量赋值一个宏实际上是一个错误码若赋值结果不为0则表示函数调用过程中出错
注意事项
1、在函数调用前将errno置为零非常重要虽然程序刚开始时errno的值默认为0但有可能在随后的函数调用中已经被改动了而库函数不会将errno清零这就需要我们人为修改了
//一系列操作
....//人为置零
errno 0;//再次函数调用
y sqrt(x);//判断调用是否成功
if(errno ! 0)
{fprintf(stderr,sqrt error; program terminated.\n) //以标准错误流stderr输出信息exit (EXIT_FAILURE); //程序退出
}
2、当发生错误时向errno中存储的值通常是EDOM和ERANGE它们代表调用数学函数时可能发生的两种错误这也是为什么说大部分使用errno变量的函数集中在math.h中C99中还增加了EILSEQ宏它主要是将一些特定头文件尤其是wchar.h头文件中的库函数在发生编码错误时将EILSEQ的值存储到errno中 EDOM 函数参数超出范围例如sqrt(-1) EILSEQ (C99) 不合法的字符顺序例如wcstombs(str, L\xffff, 2) ERANGE 函数结果超出范围例如strtol(0xfffffffff,NULL,0)
3、一些函数可能会同时导致多种错误可以用errno分别于它们比较然后确定到底发生了什么错误
简单案例
函数操作失败打印errno的值为2利用strerror函数接收errno的值并打印出具体的问题
#define _CRT_SECURE_NO_WARNINGS
#include stdio.h
#include stdlib.h
#include string.h
#include errno.hint main() {FILE* file fopen(nonexistent.txt, r);if (file NULL) {printf(Error opening file. Errno: %d\n, errno);// 或者使用 strerror 函数打印对应的错误描述信息printf(Error message: %s\n, strerror(errno));}return 0;
}函数操作成功打印errno的值为0利用strerror函数接收errno的值并打印出不存在问题
#define _CRT_SECURE_NO_WARNINGS
#include stdio.h
#include stdlib.h
#include string.h
#include errno.hint main() {FILE* file fopen(nonexistent.txt, r);if (file ! NULL) {printf(Error opening file. Errno: %d\n, errno);// 或者使用 strerror 函数打印对应的错误描述信息printf(Error message: %s\n, strerror(errno));}return 0;
}error.h头文件
一般情况下在VS中使用该头文件需要下载GUN C库
文件说明是一个 GNU C 库glibc中的头文件
概念该头文件声明了扩展错误处理函数和相关宏其中最常见且重要的是erorr和error_at_line函数这些函数允许以类似于格式化字符串输出 (printf) 的方式生成自定义格式或包含更多详细信息如源代码位置等的出错消息
功能生成自定义格式或包含更多详细信息的出错消息
error.h头文件中包含了两个函数
//error()函数
extern void error (int __status, int __errnum, const char *__format, ...)__attribute__ ((__format__ (__printf__, 3, 4)));//error_at_line()函数
extern void error_at_line (int __status, int __errnum, const char *__fname, unsigned int __lineno, const char *__format, ...)__attribute__ ((__format__ (__printf__, 5, 6)));
参数解释
_status状态码代表整体程序/调用者关心是否成功执行零表示成功非零表示不成功 状态码可以自定义也可以是约定好的标准状态码一些常见的标准错误码包括 不推荐自定义 1一般性未知错误2误用 shell 命令时引起不支持选项等126命令不可执行例如权限问题127没有找到命令128 NN为信号编号由于收到信号而导致进程终止 _errnum错误码代表具体某次操作所产生/涉及到/引发了什么样类型和内容方面问题一般都用errno的值表示_format格式化字符串和可变数量的参数用于打印出错消息_fname包含出错位置信息如源代码文件名作为字符串常量系统自动添加_lineno包含出错位置信息如源代码行号作为无符号整数值系统自动添加 关于的”__attribute__“解释 内容说明是一种 GNU C 扩展属性 作用告诉编译器函数的参数列表和格式字符串之间的关系以便进行编译时的格式检查 参数解释__format__ 是一个特殊属性名称后面跟着两个整数值第一个整数表示从第几个参数开始是格式字符串通常是形如 printf() 或 scanf() 的函数中的第一个可变参数第二个整数表示从该位置开始应用类型检查 void my_printf(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2)));上述代码定义了一个名为my_printf的函数并使用了该属性。其中 fmt 参数是作为格式字符串使用即模拟类似于标准库函数 printf() 的行为。数字 1 表示 fmt 参数在参数列表中位于索引位置1 从0开始计算而数字 2 表示类型检查应该从索引位置2 开始应用。即打印时先打印fmt后面的内容再打印fmt的内容。 通过将此属性添加到函数声明或定义上编译器可以对调用该函数时传递给它们的实际参数与预期的格式进行比较并发出警告或错误消息以帮助捕获潜在的格式错误。 关于“属性”的解释 在 C 语言中属性是用于向编译器提供额外信息或指示的机制。它们以特殊的语法形式出现并通过将属性应用于声明或定义来修改其行为或注释代码。 实例一 //使用error.h头文件中的error函数
#define _GNU_SOURCE // 需要包含此宏定义以启用 glibc 扩展功能
#include stdio.h
#include stdlib.h
#include errno.hvoid process_data(int value)
{if (value 0) {error(EXIT_FAILURE, errno, Invalid value: %d, value);} //error-1建议使用errno“如何显示提示信息可以自定义比如File error:”,%d对应的值// 处理数据...
}int main() {int data -1;process_data(data);return 0;
}//输出结果
Invalid value: %d: Invalid argument其实如果想要将输出结果格式化的话可以这样描述 自定义错误消息: 变量值: 与错误码相关的具体描述信息 至于状态码的值一般来说都会取非零值 实例二 //使用error.h头文件中的error_at_line函数
//使用error_at_line()实现在即显示错误原因的同时又显示行号
#define _GNU_SOURCE // 需要包含此宏定义以启用 glibc 扩展功能
#include stdio.h
#include stdlib.h
#include errno.h
#include error.hint main() {FILE *file fopen(nonexistent.txt, r);if (file NULL) {error_at_line(errno, errno, __FILE__, __LINE__, Failed to open file);}// 其他操作...fclose(file);return 0;
}//输出结果
./example: Failed to open file: No such file or directory (Error 2) at example.c:11其实如果想要将输出结果格式化的话可以这样描述 当前程序的名称 自定义错误信息 : 错误码对应信息 (错误码) at 当前程序名 : 问题行号 error.h与errno.h的区别
errno.h 提供了全局变量和宏来处理基本级别底层上发生的各种系统和库函数调用产生额外信息error.h 则提供了更高级别、灵活性更强的错误处理函数和宏用于生成自定义格式或包含更多详细信息的出错消息。需要注意的是error.h 是 GNU C 特定库glibc提供的功能在其他平台或编译器环境中可能不存在或有不同实现。因此在使用时应谨慎考虑可移植性和目标平台兼容性 error.h 头文件提供了一些高级别且更灵活的错误处理函数如 error 和 error_at_line这些函数可以用于生成自定义格式或包含更多详细信息的出错消息。然而在实际开发中通常会使用 errno.h 头文件中定义的 errno 全局变量和相关宏来报告和处理错误。这是因为标准库函数在执行失败时会将适当的错误码设置到 errno 变量并且许多标准库函数都依赖于该机制。使用 errno 的好处是它提供了一种统一、标准化的方式来表示和传递错误信息。通过查阅 errno.h 中定义的宏可以获得与特定错误代码对应的文本描述并根据需要进行相应处理。虽然自定义状态码或其他高级别方法可能具有更大灵活性和扩展性但直接使用errno是最常见、最简单并与现有代码兼容度较高的方式
补充内容
1~34号错误码在Linux中的/usr/include/asm-generic/errno-base.h目录下使用cat指令查看
#define EPERM 1 /*不允许操作*/
#define EPERM 1 /* Operation not permitted */#define ENOENT 2 /*没有这样的文件或目录*/
#define ENOENT 2 /* No such file or directory */#define ESRCH 3 /* 没有这样的进程 */
#define ESRCH 3 /* No such process */#define EINTR 4 /*中断的系统调用*/
#define EINTR 4 /* Interrupted system call */#define EIO 5 /* I/O错误*/
#define EIO 5 /* I/O error */#define ENXIO 6 /*没有这样的设备或地址*/
#define ENXIO 6 /* No such device or address */#define E2BIG 7 /* Arg list太长*/
#define E2BIG 7 /* Arg list too long */#define ENOEXEC 8 /*执行格式错误*/
#define ENOEXEC 8 /* Exec format error */#define EBADF 9 /*错误的文件号*/
#define EBADF 9 /* Bad file number */#define ECHILD 10 /*没有子进程*/
#define ECHILD 10 /* No child processes */#define EAGAIN 11 /*重试*/
#define EAGAIN 11 /* Try again */#define ENOMEM 12 /*内存不足*/
#define ENOMEM 12 /* Out of memory */#define EACCES 13 /*权限被拒绝*/
#define EACCES 13 /* Permission denied */#define EFAULT 14 /*错误地址*/
#define EFAULT 14 /* Bad address */#define ENOTBLK 15 /*需要的块设备*/
#define ENOTBLK 15 /* Block device required */#define EBUSY 16 /*设备或资源忙*/
#define EBUSY 16 /* Device or resource busy */#define EEXIST 17 /*文件存在*/
#define EEXIST 17 /* File exists */#define EXDEV 18 /*跨设备链接*/
#define EXDEV 18 /* Cross-device link */#define ENODEV 19 /*没有这样的设备*/
#define ENODEV 19 /* No such device */#define ENOTDIR 20 /*不是一个目录*/
#define ENOTDIR 20 /* Not a directory */#define EISDIR 21 /*是一个目录*/
#define EISDIR 21 /* Is a directory */#define EINVAL 22 /*无效参数*/
#define EINVAL 22 /* Invalid argument */#define ENFILE 23 /*文件表溢出*/
#define ENFILE 23 /* File table overflow */#define EMFILE 24 /*打开的文件太多*/
#define EMFILE 24 /* Too many open files */#define ENOTTY 25 /*不是打字机*/
#define ENOTTY 25 /* Not a typewriter */#define ETXTBSY 26 /*文本文件繁忙*/
#define ETXTBSY 26 /* Text file busy */#define EFBIG 27 /*文件太大*/
#define EFBIG 27 /* File too large */#define ENOSPC 28 /*设备上没有空格*/
#define ENOSPC 28 /* No space left on device */#define ESPIPE 29 /*非法查找*/
#define ESPIPE 29 /* Illegal seek */#define EROFS 30 /*只读文件系统*/
#define EROFS 30 /* Read-only file system */#define EMLINK 31 /*链接太多*/
#define EMLINK 31 /* Too many links */#define EPIPE 32 /*破裂的管道*/
#define EPIPE 32 /* Broken pipe */#define EDOM 33 /*数学参数的域的func */
#define EDOM 33 /* Math argument out of domain of func */#define ERANGE 34 /*数学结果不可表示*/
#define ERANGE 34 /* Math result not representable */
35~134号错误码在Linxu中的/usr/include/asm-generic/errno.h目录下使用cat指令查看
#define EDEADLK 35 /*将发生资源死锁*/
#define EDEADLK 35 /* Resource deadlock would occur */#define ENAMETOOLONG 36 /*文件名太长*/
#define ENAMETOOLONG 36 /* File name too long */#define ENOLCK 37 /*没有可用的记录锁*/
#define ENOLCK 37 /* No record locks available */#define ENOSYS 38 /*函数未实现*/
#define ENOSYS 38 /* Function not implemented */#define ENOTEMPTY 39 /*目录不为空*/
#define ENOTEMPTY 39 /* Directory not empty */#define ELOOP 40 /*遇到太多符号链接*/
#define ELOOP 40 /* Too many symbolic links encountered */#define EWOULDBLOCK EAGAIN /*操作将阻塞*/
#define EWOULDBLOCK EAGAIN /* Operation would block */#define ENOMSG 42 /*没有指定类型的消息*/
#define ENOMSG 42 /* No message of desired type */#define EIDRM 43 /*标识符删除*/
#define EIDRM 43 /* Identifier removed */#define ECHRNG 44 /*通道号超出范围*/
#define ECHRNG 44 /* Channel number out of range */#define EL2NSYNC 45 /* 2级未同步 */
#define EL2NSYNC 45 /* Level 2 not synchronized */#define EL3HLT 46 /* 3级停止 */
#define EL3HLT 46 /* Level 3 halted */#define EL3RST 47 /* 3级复位*/
#define EL3RST 47 /* Level 3 reset */#define ELNRNG 48 /*链路数超出范围*/
#define ELNRNG 48 /* Link number out of range */#define EUNATCH 49 /*协议驱动程序未连接*/
#define EUNATCH 49 /* Protocol driver not attached */#define ENOCSI 50 /*没有CSI结构可用*/
#define ENOCSI 50 /* No CSI structure available */#define EL2HLT 51 /*二级暂停*/
#define EL2HLT 51 /* Level 2 halted */#define EBADE 52 /*无效的交换*/
#define EBADE 52 /* Invalid exchange */#define EBADR 53 /*无效请求描述符*/
#define EBADR 53 /* Invalid request descriptor */#define EXFULL 54 /* 完整交换 */
#define EXFULL 54 /* Exchange full */#define ENOANO 55 /*无阳极*/
#define ENOANO 55 /* No anode */#define EBADRQC 56 /*无效请求码*/
#define EBADRQC 56 /* Invalid request code */#define EBADSLT 57 /*无效槽位*/
#define EBADSLT 57 /* Invalid slot */#define EDEADLK
#define EDEADLOCK EDEADLK#define EBFONT 59 /*错误的字体文件格式*/
#define EBFONT 59 /* Bad font file format */#define ENOSTR 60 /*设备不是流*/
#define ENOSTR 60 /* Device not a stream */#define ENODATA 61 /*没有可用的数据*/
#define ENODATA 61 /* No data available */#define ETIME 62 /* 计时器过期 */
#define ETIME 62 /* Timer expired */#defien ENOSR 63 /*流出流资源*/
#define ENOSR 63 /* Out of streams resources */#define ENONET 64 /*机器不在网络上*/
#define ENONET 64 /* Machine is not on the network */#define ENOPKG 65 /*未安装的包*/
#define ENOPKG 65 /* Package not installed */#define EREMOTE 66 /*对象是远程*/
#define EREMOTE 66 /* Object is remote */#define ENOLINK 67 /*链接已被切断*/
#define ENOLINK 67 /* Link has been severed */#define EADV 68 /*发布错误*/
#define EADV 68 /* Advertise error */#define ESRMNT 69 /* Srmount错误*/
#define ESRMNT 69 /* Srmount error */#define ECOMM 70 /*发送通信错误*/
#define ECOMM 70 /* Communication error on send */#define EPROTO 71 /*协议错误*/
#define EPROTO 71 /* Protocol error */#define EMULTIHOP 72 /*尝试多跳*/
#define EMULTIHOP 72 /* Multihop attempted */#define EDOTDOT 73 /* RFS特定错误*/
#define EDOTDOT 73 /* RFS specific error */#define EBADMSG 74 /*不是数据消息*/
#define EBADMSG 74 /* Not a data message */#define EOVERFLOW 75 /*对于定义的数据类型值太大*/
#define EOVERFLOW 75 /* Value too large for defined data type */#define ENOTUNIQ 76 /*名称在网络上不是唯一的*/
#define ENOTUNIQ 76 /* Name not unique on network */#define EBADFD 77 /*坏状态的文件描述符*/
#define EBADFD 77 /* File descriptor in bad state */#define EREMCHG 78 /*远程地址更改*/
#define EREMCHG 78 /* Remote address changed */#define ELIBACC 79 /*不能访问所需的共享库*/
#define ELIBACC 79 /* Can not access a needed shared library */#define ELIBBAD 80 /*访问一个损坏的共享库*/
#define ELIBBAD 80 /* Accessing a corrupted shared library */#define ELIBSCN 81 /* .lib section in a.out已损坏*/
#define ELIBSCN 81 /* .lib section in a.out corrupted */#define ELIBMAX 82 /*试图链接过多的共享库*/
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */#define ELIBEXEC 83 /* 不能直接执行共享库*/
#define ELIBEXEC 83 /* Cannot exec a shared library directly */#define EILSEQ 84 /*非法字节序列*/
#define EILSEQ 84 /* Illegal byte sequence */#define ERESTART 85 /*中断的系统调用应该重启*/
#define ERESTART 85 /* Interrupted system call should be restarted */#define ESTRPIPE 86 /*流管道错误*/
#define ESTRPIPE 86 /* Streams pipe error */#define EUSERS 87 /*用户过多*/
#define EUSERS 87 /* Too many users */#define ENOTSOCK 88 /*非套接字的套接字操作*/
#define ENOTSOCK 88 /* Socket operation on non-socket */#define EDESTADDRREQ 89 /*需要的目的地址*/
#define EDESTADDRREQ 89 /* Destination address required */#define EMSGSIZE 90 /*消息太长*/
#define EMSGSIZE 90 /* Message too long */#define EPROTOTYPE 91 /*协议类型错误的套接字*/
#define EPROTOTYPE 91 /* Protocol wrong type for socket */#define ENOPROTOOPT 92 /*协议不可用*/
#define ENOPROTOOPT 92 /* Protocol not available */#define EPROTONOSUPPORT 93 /*不支持协议*/
#define EPROTONOSUPPORT 93 /* Protocol not supported */#define ESOCKTNOSUPPORT 94 /* Socket类型不支持*/
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */#define EOPNOTSUPP 95 /*不支持传输端点上的操作*/
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */#define EPFNOSUPPORT 96 /*不支持协议族*/
#define EPFNOSUPPORT 96 /* Protocol family not supported */#define EAFNOSUPPORT 97 /*协议不支持的地址族
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */#define EADDRINUSE 98 /*地址已被使用*/
#define EADDRINUSE 98 /* Address already in use */#define EADDRNOTAVAIL 99 /*无法分配请求的地址*/
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */#define ENETDOWN 100 /*网络关闭*/
#define ENETDOWN 100 /* Network is down */#define ENETUNREACH 101 /*网络不可达*/
#define ENETUNREACH 101 /* Network is unreachable */#define ENETRESET 102 /*由于复位导致网络连接断开*/
#define ENETRESET 102 /* Network dropped connection because of reset */#define ECONNABORTED 103 /*软件导致的连接中止*/
#define ECONNABORTED 103 /* Software caused connection abort */#define ECONNRESET 104 /*连接复位*/
#define ECONNRESET 104 /* Connection reset by peer */#define ENOBUFS 105 /*没有可用的缓冲区空间*/
#define ENOBUFS 105 /* No buffer space available */#define EISCONN 106 /*传输端点已经连接*/
#define EISCONN 106 /* Transport endpoint is already connected */#define ENOTCONN 107 /*传输端点未连接*/
#define ENOTCONN 107 /* Transport endpoint is not connected */#define eshudown108 /*在传输端点关闭后不能发送*/
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */#define ETOOMANYREFS 109 /*引用太多:无法拼接*/
#define ETOOMANYREFS 109 /* Too many references: cannot splice */#define ETIMEDOUT 110 /*连接超时*/
#define ETIMEDOUT 110 /* Connection timed out */#define ECONNREFUSED 111 /*拒绝连接*/
#define ECONNREFUSED 111 /* Connection refused */#define EHOSTDOWN 112 /*主机已关闭*/
#define EHOSTDOWN 112 /* Host is down */#define EHOSTUNREACH 113 /*没有到主机的路由*/
#define EHOSTUNREACH 113 /* No route to host */#define EALREADY 114 /*操作已经在进行中*/
#define EALREADY 114 /* Operation already in progress */#define EINPROGRESS 115 /*操作正在进行中*/
#define EINPROGRESS 115 /* Operation now in progress */#define ESTALE 116 /*过期的NFS文件句柄*/
#define ESTALE 116 /* Stale NFS file handle */#define EUCLEAN 117 /*结构需要清洗*/
#define EUCLEAN 117 /* Structure needs cleaning */#define ENOTNAM 118 /*不是XENIX命名类型文件*/
#define ENOTNAM 118 /* Not a XENIX named type file */#define ENAVAIL 119 /*没有XENIX信号量可用*/
#define ENAVAIL 119 /* No XENIX semaphores available */#define EISNAM 120 /*是一个命名类型文件*/
#define EISNAM 120 /* Is a named type file */#define EREMOTEIO 121 /*远程I/O错误*/
#define EREMOTEIO 121 /* Remote I/O error */#define EDQUOT / /*配额已超过*/
#define EDQUOT 122 /* Quota exceeded */#define ENOMEDIUM 123 /*没有找到介质*/
#define ENOMEDIUM 123 /* No medium found */#define EMEDIUMTYPE 124 /*错误的介质类型*/
#define EMEDIUMTYPE 124 /* Wrong medium type */#define ECANCELED 125 /* 操作取消 */
#define ECANCELED 125 /* Operation Canceled */#define ENOKEY 126 /* 所需密钥不可用 */
#define ENOKEY 126 /* Required key not available */#define EKEYEXPIRED 127 /* 密钥已过期 */
#define EKEYEXPIRED 127 /* Key has expired */#define EKEYREVOKED 128 /* 密钥已被撤销 */
#define EKEYREVOKED 128 /* Key has been revoked */#define EKEYREJECTED 129 /* 服务拒绝了密钥 */
#define EKEYREJECTED 129 /* Key was rejected by service *//* 对于健壮的互斥锁 */
/* for robust mutexes */#define EOWNERDEAD 130 /* 主人死后 */
#define EOWNERDEAD 130 /* Owner died */#define ENOTRECOVERABLE 131 /* 不可恢复状态 */
#define ENOTRECOVERABLE 131 /* State not recoverable */#define ERFKILL 132 /* 由于射频杀伤无法操作 */
#define ERFKILL 132 /* Operation not possible due to RF-kill */#define EHWPOISON 133 /* 内存页有硬件错误 */
#define EHWPOISON 133 /* Memory page has hardware error */~over~