原文出处:http://mylinuxbook.com/error-handling-in-c-programming-on-linux/
本文主要介绍了全局变量errno的用法及相关函数:strerror()、strerror_r()、perror()。我们可以在调用某个函数后检查errno的值,从而获知函数执行的过程中发生了什么,以下是一个简单的例子,在这段代码中,我们试图以只读方式打开一个并不存在的文件:
#include<stdio.h>
#include<errno.h>
int main(void)
{
FILE *fd = NULL;
// Reset errno to zero before calling fopen().
errno = 0;
// Lets open a file that does not exist
fd = fopen("Linux.txt","r");
if(errno)
{
printf("\n fopen() failed: errno = %d\n", errno);
}
return 0;
}
在fopen调用前我们将errno的值置为0,在fopen()调用后我们可以通过检查errno的值来判断是否成功打开了文件,以下是执行结果:
fopen() failed: errno = 2
可以看到fopen()函数中将errno的值设为2,以指示没有成功打开文件。然后,errno是一个数字,很多时候我们需要看到更直观的错误信息,这就用到了strerror(),该函数会把errno的值转换成一个可读的字符串,见下例:
#include<stdio.h>
#include<errno.h>
#include<string.h>
int main(void)
{
FILE *fd = NULL;
// Reset errno to zero before calling fopen().
errno = 0;
// Lets open a file that does not exist
fd = fopen("Linux.txt","r");
if(errno)
{
// Use strerror to display the error string
printf("\nThe function fopen failed due to : [%s]\n",(char*)strerror(errno)); //#1
return -1;
}
return 0;
}
程序的输出结果如下:
The function fopen failed due to : [No such file or directory]
这样我们就可以直观地看到哪里出了错,但是strerror()有一个问题,就是strerror()返回的字符串存储在一个公共的区域,也就是,说如果其他线程也调用了这个函数,而且传入了一个不同的errno值,那么这个字符串会被覆盖掉。为了解决这个问题,所以有了strerro_r(),该函数会接受一个buf作为参数,然后将字符串存在这个buf中。perror()的出现也是为了输出一个可读的错误信息,只是这个信息被输出到了stderr上,用perror()可以替代上面代码中的输出语句#1,如下:
perror("The function fopen failed due to");
输出结果页很相似:
The function fopen failed due to: No such file or directory
需要注意的是:perror没有将errno作为参数,而是在内部直接读取了errno的值。