
errno用于保存最后的错误代码. 它是一个宏,已扩展为int类型的数据(在单线程程序中可以视为全局变量),并且当前程序具有读取和写入权限. 错误代码的概念将在操作过程中产生各种错误. 我们可以为每种错误类型分配一个唯一的编号,就像为班级中的学生分配一个学生编号一样. 在C语言中,我们称之为错误代码.
错误代码只是一个数字,没有其他结构. 要获取特定的错误信息,通常有两种选择:
此外,最好在调用函数之前将errno的值重置为0. 因为前一个函数可能已经设置了errno的值,所以如果我们不将errno设置为0,那么即使当前函数没有错误,我们也会读取非零值,并错误地认为当前函数有一个错误,这显然是不可靠的. 实例获取fopen()函数的错误信息.

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{
errno = 0; //将 errno 设置回 0 值
FILE *fp = fopen("D:/demo.txt", "r");
if(fp){
printf("Congratulations, the file opens successfully!\n");
}else{
printf("Error no.%d: %s\n", errno, strerror(errno));
}
return 0;
}
如果D驱动器中没有demo.txt文件,则运行结果为:
错误2: 没有此类文件或目录. 让我们谈谈错误代码的早期C标准(C89和C99). 在
宏描述
EDOM
域错误. 一些数学函数仅对一定范围内的值有意义. 我们称这个范围为域. 例如,sqrt()函数只能平方根非负数. 如果我们向sqrt()传递一个负数,那么sqrt()会将errno设置为EDOM.
ERANGE
范围错误. 变量可以表示的值的范围是有限的. 如果值太大或太小,都有溢出的危险. 例如,pow()用于查找数字的幂fopen错误码,其结果最有可能超出浮点型变量的表示范围. 对于另一个示例,strtod()用于将字符串转换为浮点数,否则它可能会超出范围. . 在这些情况下,errno设置为ERANGE.
EILSEQ
非法序列. 它源自非法字符序列(可以理解为字符串). 使用mbrtowc(),wcrtomb()之类的功能在多字节字符和宽字符之间进行转换时,如果遇到无效字符,请将errno设置为EILSEQ. 例如,在wcrtomb(buffer,L'\ xfffff',&mbs);中. 声明,L'\ xfffff'是超出范围的宽字符,这是一个非法字符序列,wcrtomb()会将errno设置为EILSEQ.
程序中可能会出现数百或数千个错误.
有关Windows下errno的描述,请滑动:
请在Linux下对errno进行描述: C11标准的三个宏仍然太少,并且没有太多实用价值. C标准委员会也意识到了这个问题,因此在最新的C11标准中,它将是可移植的. 宏的数量已扩展到78,其中包含POSIX环境中已经存在的许多名称. 一些有关多线程安全的教程说errno扩展为int类型的全局变量,如下所示:
extern int _errno; #define errno _errno
许多单线程库也做同样的事情. 但是此解决方案仅适用于单线程程序,不适用于多线程程序. 全局变量的范围是整个程序,所有源文件,而不仅仅是当前源文件. 在多线程程序中fopen错误码,线程之间存在竞争. 每个线程交替使用CPU时间. 将errno设置为全局变量会导致一个严重的问题: 线程A中的函数会修改errno的值,并且还没有时间读取它. 它挂起,并且线程B在获得CPU时间后修改errno的值. 当线程A在“唤醒”后读取errno的值时,它找不到原始值,只能读取线程B的设置. 值,线程A对此一无所知.
要解决此问题,您不能在全局范围内定义errno,但必须为每个线程定义自己的errno,因此许多支持多线程的库都将errno实现为一个函数. 看起来像这样:
#if define _MULTI_THREAD #define errno (*_errno_func()) #endif
_MULTI_THREAD是启用多线程后定义的宏. 线程内errno变量的地址可以通过_errno_func()函数获得,而errno变量本身可以通过在前面加上*来获得. 该代码着重于说明原理,假定使用的宏名称和函数名称,而实际的库实现不使用这些名称.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-276886-1.html
我选择也觉得我要换新一下我自己的生活了
o
等上面看穿了
中华士魄