C语言获取系统错误

摘要:
目录1。strerror函数2。错误号的详细信息。1.调用库函数失败不一定会设置errno2。errno不能用作调用库函数失败的标志。3.程序员不能使用errno。3.课后作业4。版权声明。编写程序时,我们需要调用C语言提供的库函数。库函数调用通常不会直接返回错误代码。在<Strerror()用于根据参数errno的错误代码查询错误原因的描述字符串。

目录

我们在写程序的时候需要调用C语言提供的库函数,并通过函数的返回值判断调用是否成功。其实在C语言中,还有一个全局变量errno,存放了函数调用过程中产生的错误码。

为防止和正常的返回值混淆,库函数的调用一般并不直接返回错误码,而是将错误码(是一个整数值,不同的值代表不同的含义)存入一个名为errno 的全局变量中,errno 不同数值所代表的错误消息定义在 <errno.h>文件中。如果库函数调用失败,可以通过读出 errno的值来确定问题所在,推测程序出错的原因,这也是调试程序的一个重要方法。

配合 strerror和perror两个库函数,可以很方便地查看出错的详细信息。

strerror 在 <string.h> 中声明,用于获取错误码对应的消息描述。

perror 在 <stdio.h>中声明,用于在屏幕上最近一次系统错误码及其消息描述,在实际开发中,我们写的程序运行于后台,在屏幕上显示错误信息没有意义。

一、strerror函数

函数声明:

char *strerror(int errno);

函数说明:strerror()用来依参数errno的错误代码来查询其错误原因的描述字符串,然后将该字符串指针返回。

返回值:返回描述错误原因的字符串地址。

在gcc4.4.7版本中,定义了131个错误代码,我们用程序把它们全部显示出来。

示例(book158.c)

/*
 * 程序名:book158.c,此程序演示strerror函数的使用。
 * 作者:C语言技术网(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>

int main()
{
  int errorno;

  for(errorno=0;errorno<132;errorno++)
  {
    printf("%d:%s
",errorno,strerror(errorno));
  }
}

输出效果
在这里插入图片描述

一共有131个错误代码和描述,上面的截图只显示了前5条和最后5条。这些错误代码和描述看一下就行了,不需要记住。

二、errno的细节

1、调用库函数失败不一定会设置errno

如果库函数调用失败,库函数会设置errno的值,程序员通过 errno的值来判断出错的具体原因,但是,并不是全部的库函数在调用失败时都会设置errno的值,那么,哪些库函数会设置errno的值呢,要看函数的说明,例如fopen函数,在命令行下输入man fopen,在诸多的文字中,有以下行说明文字。

The fopen() function may also fail and set errno for any of the errors specified for the routine open(2).

不属于系统调用的函数不会设置errno,属于系统调用的函数才会设置errno。

2、errno不能作为调用库函数失败的标志

在 C 语言中,如果库函数被正确地执行,那么 errno 的值不会被清零。换句话说,errno的值只有在一个库函数调用发生错误时才会被设置,当库函数调用成功运行时,errno的值不会被修改,当然也不会主动被置为0。也正因为如此,在实际编程中,判断函数执行是否成功还得靠函数的返回值,只有在返回值是失败的情况下,才需要关注errno的值。

3、程序员可以不用errno

关注errno的目的是为了获取更详细错误信息,这些错误信息对程序员诊断程序可能会有帮助,但不是必须的。

示例(book160.c)

/*
 * 程序名:book160.c,此程序用于演示C程序的基本结构。
 * 作者:C语言技术网(www.freecplus.net) 日期:20190525
*/
/* 
 *  此程序演示errno全局变量和strerror函数
 *  作者:豫让 日期:20190601
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{
  FILE *fp=0;     // 定义文件指针变量fp

  // 以只读的方式打开文件/tmp/book1.c
  if ( (fp=fopen("/tmp/book1.c","r")) == 0 )
  {
    printf("打开文件/tmp/book1.c失败(%d:%s)。
",errno,strerror(errno)); 
  }
  
  // 关闭文件
  if ( fp!=0 ) fclose(fp);

  return 0;
}

运行效果

在这里插入图片描述

三、课后作业

编写示例程序,把本章节介绍的知识点全部演示一遍,用程序演示可以加深您的理解和映象。

四、版权声明

C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。
来源:C语言技术网(www.freecplus.net)
作者:码农有道

如果文章有错别字,或者内容有错误,或其他的建议和意见,请您留言指正,非常感谢!!!

免责声明:文章转载自《C语言获取系统错误》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Eclipse paho学习笔记Thinkphp6笔记十三:验证器(场景验证)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

TS Eslint规则说明

"no-alert": 0,//禁止使用alert confirm prompt "no-array-constructor": 2,//禁止使用数组构造器 "no-bitwise": 0,//禁止使用按位运算符 "no-caller": 1,//禁止使用arguments.caller或arguments.callee "no-catch-sha...

php中session_start()相关问题分析与解决办法

介绍下,在php中使用session时遇到的一些问题,与相关解决方法。1.错误提示Warning: Cannot send session cookie - headers already sentWarning: Cannot send session cache limiter - headers already sent分析及解决办法这一类问题,的原...

__attribute__的一些相关属性

__attribute__((format()))  这个format有3个参数。 int my(NSString *str,NSString *str1,NSArray*str2,...) __attribute__((format(__NSString__,2,4)));   三个参数告诉编译器,第二个参数必须是NSString类型,且可变参数从第4位...

matlab中类的定义和使用

通常一个类应该包含四个基本的成员函数:构造函数 ―― 与类名相同,可以在其中完成成员初始化的工作;显示函数 ―― 名为display,用于显示成员的数据;赋值函数 ―― 名为set,用于设置类成员的数值;取值函数 ―― 名为get,用于读取类成员的函数。    与C++的类不同的是,MATLAB的类不需要特别的析构函数。如果类用到了一些特殊的内容需要释放的...

Lodash学习笔记

有多年开发经验的工程师,往往都会有自己的一套工具库,称为utils、helpers等等,这套库一方面是自己的技术积累,另一方面也是对某项技术的扩展,领先于技术规范的制订和实现。 Lodash就是这样的一套工具库,它内部封装了诸多对字符串、数组、对象等常见数据类型的处理函数,其中部分是目前ECMAScript尚未制订的规范,但同时被业界所认可的辅助函数。莫倩...

书单 (动态更新书单)

C++ primer 5th Unix/linux 系统管理手册 深入理解C++对象模型 STL源码刨析 More Effeetive C++  Linux 多线程服务器编程 Unix环境高级编程 C++并发编程实践 Effective Modern C++ C++ 标准库 The rust programming language 编程珠玑 数据结构C+...