#include <stdio.h> // void perror(const char *msg);

#include <string.h> // char *strerror(int errnum);

#include <errno.h> //errno

 

errno 是错误代码,在 errno.h头文件中;

perror是错误输出函数,输出格式为:msg:errno对应的错误信息(加上一个换行符);

strerror 是通过参数 errnum (就是errno),返回对应的错误信息。

以下是测试程序:

--------------------------------------------------------------------

// p_str_error.c

// perror , strerror 函数 , errno 测试

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <errno.h>

int main(int argc, char *argv[])

{

 FILE *fp;

 char *buf;

 if( (fp = fopen(argv[1], "r")) == NULL)

 {

  perror("perror"); // 好方便

  errno = 12;

  printf("strerror: %s\n", strerror(errno)); //转换错误码为对应的错误信息

  exit(1);

 }

 perror("perror");

 errno = 13;

 printf("strerror: %s\n", strerror(errno));

 
 

 fclose(fp); 

 return 0;

}

 

--------------------------------------------------------------------

输入一个存在的文件名,如:./a.out 111

open失败则会输出:

perror: No such file or directory

strerror: Cannot allocate memory

open成功则会输出:

perror: Success

strerror: Permission denied

很明显,perror信息是由 perror函数输出的了,第二行是 strerror通过将 errno 轮换成对应的错误信息打印出来。

这次就写这么多了,程序简单,没啥好说的了。

最近在搭建开发环境,设计整个系统架构了。花了六年时间研发的系统,终于上线了。

我要用多少时间来学习呢,还好有资料,有源码,学习起来还不算吃力,嘿嘿。。。。。。

我要写一套山寨版的^_^!!!

 
 

 
 

 

 

 

 

<stdio.h>中定义了perror(),perror是在标准输出上输出msg字符串,然后再后面加上:错误语段(这个错误语段对应这时的errno) 

 

<string.h>中定义了strerror(),strerror是把一个错误numb作为参数,然后返回错误numb所对应的错误语段,一般用errno。

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <string.h>

#include <errno.h>

 

int main(int argc, char* argv[])

{

int i=open("/usr/src/s.t",0);

perror(argv[0]);

printf(strerror(errno));

return 0;

}

 

执行结果:

]$./test 

./test: No such file or directory

No such file or directory

 

),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。 

 

C标准定义了__LINE__和__FILE__宏,GNU C扩展中定义了__FUNCTION__宏,可以用来实现代码跟踪调试。这是三个非常有用的全局变量,当程序需要输出一些内容,而又想知道输出的内容是在哪里输出的时候,这几个全局变量就派上用场了。__FILE__,__FUNCTION__, __LINE__ 从名字可以直接看出来了,对应的:代码文件名, 函数名, 行号。 

 

<errno.h>中定义了errno,注意没有函数会将errno清零,所以在调用可能设置errno的函数之前先将errno清零。但是errno是一个数字,代表的具体含义还要到errno.h中去阅读宏定义,而每次查阅是一件很繁琐的事情。所以经常char *strerror(int errno)将错误代码转换为字符串错误信息,可以将该字符串和其它的信息组合输出到用户界面。 

 

<stdlib.h>中定义了abort()、exit()和atexit()函数。 

 

函数abort()将导致程序异常终止,在终止前程序没有机会执行atexit()登记的函数,也没有计划执行一些常规的清除工作。同时,abort()还会产生core dump,如果没有ulimit限制的话。 

 

函数exit()和abort()类似,但它在完成清理工作之后才终止程序。 

 

函数atexit()登记在程序正常终止时要调用的函数。 

 

<syslog.h>中定义了syslogd的接口,常用于系统日志。

 

 

 

 

 

 

 

Linux/Unix C编程之的perror函数,strerror函数,errno

#include <stdio.h> // void perror(const char *msg);

#include <string.h> // char *strerror(int errnum);

#include <errno.h> //errno

errno是错误代码,在errno.h头文件中

void perror(const char *s)

perror是错误输出函数,在标准输出设备上输出一个错误信息。

参数s一般是参数错误的函数

例如perror("fun"),其输出为:fun:后面跟着错误信息(加上一个换行符)

char *strerror(int errnum);通过参数errnum(也就是errno),返回错误信息

以下是测试程序:

[cpp] view plaincopy

  1. //程序名:errtest.c,环境为linux  
  2.   
     
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <string.h>  
  6. #include <errno.h>  
  7. int main(int argc,char *argv[]){  
  8. FILE *fp;  
  9. char *buf;  
  10. if((fp=fopen(argv[1],"r"))==NULL)  
  11. {  
  12. perror("perror");  
  13. printf("sterror:%s\n",strerror(errno));  
  14. exit(1);  
  15. }  
  16. perror("perror");  
  17. errno=13;  
  18. printf("strerror:%s\n",strerror(errno));  
  19. fclose(fp);  
  20. return 0;  
  21. }  
  22.   
     
  23. 编译为errtest  

如果输入这样的命令格式./errtest 111.c(其中111.c不存在)

输出为:

perror: No such file or directory

sterror:Illegal seek

就是两个都是输出到屏幕上来了。而且sterror函数通过errno得到错误代码

如果命令格式为./errtest 111.c > out.c(其中111.c不存在)

把输出重定位到out.c文件中,会发现屏幕输出为:

perror: No such file or directory

就是说函数perror始终输出到标准输出设备上。而printf输出到文件中了

如果命令格式为./errtest 222.c(其中222.c存在)

屏幕输出为:

perror: Success

strerror: Permission denied(通过errno=12得到的一个信息)

 

 

 

 

 

 

 

 

 

 

 

 

关于errno与perror,strerror函数

errno是一个由POSIX和ISO C标准定义的符号,看(用)起来就好像是一个整形变量。当系统调用或库函数发生错误的时候,比如以只读方式打开一个不存在的文件时,它的值将会被改变,根据errno值的不同,我们就可以知道自己的程序发生了什么错误,然后进行相应的处理。有人说,函数不是可以返回值吗,根据返回值照样可以判断程序在哪里出错了,为什么还需要errno?如果你有这样的疑问,推荐你看下这篇文章

为什么,要强调errno看起来好像是一个整形变量呢?因为有的标准(如ISO C)只规定了errno的作用,而没有规定它的实现方式,它可能被定义成一个变量,也有可能被定义成一个宏,这个具体要看编译器自己的实现。早些时候,POSIX.1曾把errno定义成extern int errno这种形式,但现在这种方式比较少见了。因为以这种形式来实现errno,在多线程环境下errno变量是被多个线程共享的,这样可能线程A发生某些错误改变了errno的值,线程B虽然没有发生任何错误,但是当它检测errno的值的时候,线程B会以为自己发生了错误。所以现在errno在Linux中被实现成extern int * __errno_location(void): #define errno (*__errno_location()),这样每个线程都有自己的errno,不会再发生混乱了。

 

perror和strerror函数都是用来打印错误提示信息的,它们的原型分别是:

char *strerror(int errnum);

的话,它就会返回"Cannot allocate memory"。

void  perror(const char *s);

,调用perror("ABC"),会输出"ABC: Cannot allocate memory"。

 

关于errno有三点需要特别注意:

、如果系统调用或库函数正确执行的话,errno的值是,注意这里是不会被清零,不是不会被改变)的,假若执行函数A的时候发生了错误errno被改变,接下来直接执行函数B,如果函数B正确执行的话,errno还保留函数A发生错误时被设置的值。所以,在利用errno之前,最好先对函数的返回值进行判断,看是否发生了错误,返回值错误再利用errno判断时哪里发生了错误。所以如果一个函数无法从返回值上判断正误,而只能通过errno来判断出错,那你在调用它之前必须手动将errno清零

、系统调用或库函数正确执行,并不保证errno的值不会被改变!

、任何错误号(即发生错误时errno的取值)都是非0的。

综上所述,当需要用errno来判断函数是否正确执行的时候,最好先将errno清零,函数执行结束时,通过其返回值判断函数是否正确执行,若没有正确执行,再根据errno判断时哪里发生了错误。

 

 

 

 

perror函数和strerror函数的区别

首先简单说一下file descriptors(文件描述符)

      file descriptor 0是standard input (stdin标准输入)

      file descriptor 1 是 standard output (stdout标准输出) 

      file descriptor 2 是 standard error output(stderr标准错误输出)

 
 

 
 

perror()原型:

 
 

#include <stdio.h>

void perror(const char *msg);

它是基于errno的当前值,在标准出错上产生一条出错信息,然后返回。它首先输出由msg指向的字符串,然后是一个冒号,一个空格,接着是对应于errno值的出错信息,最后是一个换行符。

 
 

strerror()原型:

 
 

#include <string.h>

char * strerror(int errnum);

此函数将errnum(它通常就说errno值)映射为一个出错信息字符串,并返回此字符串的指针。

 
 

区别:

查看man手册,

上,若你的程序将标准错误输出重定向到/dev/null,那就看不到了,就不能用perror了。而 strerror的作用只是将errno对应的错误消息字符串返回,要怎样处理完全由你自己决定。通常我们选择把错误消息保存到日志文件中,即写文件,所以通常可以用fprintf(fp, "%s", strerror(errno))将错误消息打印到fp指向的文件中。其中perror中errno对应的错误消息集合跟strerror是一样的,也就是说不会漏掉某些错误。

 
 

可以通过一个程序示例下:

 
 

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<errno.h>

 

int main(int argc,char *argv[])

{

        FILE * fp;

 


					if((fp = fopen(argv[1],"r"))==NULL)

        {

                perror("perror");

                printf("fork error:%s\n",strerror(errno));

                exit(1);

        }

        perror("perror");

        printf("fork error:%s\n",strerror(errno));

 


					return
							0;

}

 
 

 
 

运行测试如下:

 
 

zjf@zjf:~/work/code/procise/application/chapter_1$ ./a.out
						

perror: Bad address

fork error:Bad address

zjf@zjf:~/work/code/procise/application/chapter_1$ ./a.out
							2> file

fork error:Invalid argument

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Linux/Unix C编程之的perror函数,strerror函数,errno的更多相关文章

  1. linux/unix网络编程之epoll

    转载自 Linux epoll模型 ,这篇文章讲的非常详细! 定义: epoll是Linux内核为处理大批句柄而作改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显 ...

  2. linux/unix网络编程之 select

    转自http://www.cnblogs.com/zhuwbox/p/4221934.html linux 下的 select 知识点 unp 的第六章已经描述的很清楚,我们这里简单的说下 selec ...

  3. linux/unix网络编程之 poll

    转自http://www.cnblogs.com/zhuwbox/p/4222382.html poll 与 select 很类似,都是对描述符进行遍历,查看是否有描述符就绪.如果有就返回就绪文件描述 ...

  4. Linux下多进程编程之exec函数语法及使用实例

    exec函数族 1)exec函数族说明 fork()函数用于创建一个子进程,该子进程几乎复制了父进程的全部内容,但是,这个新创建的进程如何执行呢?exec函数族就提供了一个在进程中启动另一个程序执行的 ...

  5. 深入浅出--UNIX多进程编程之fork()函数

    0前言 上周都在看都在学习unix环境高级编程的第八章--进程控制.也就是这一章中.让我理解了unix中一些进程的原理.以下我就主要依照进程中最重要的三个函数来进行解说.让大家通过阅读这一篇文章彻底明 ...

  6. unix网络编程之listen()详解

    转自于:http://blog.csdn.net/ordeder/article/details/21551567 Unix网络编程描述如下: #include <sys/socket.h> ...

  7. python3 第二十四章 - 函数式编程之Anonymous function(匿名函数)

    匿名函数指一类无须定义标识符的函数或子程序.Python用lambda语法定义匿名函数,只需用表达式而无需申明.lambda语法的定义如下: lambda [arg1 [,arg2, ... argN ...

  8. Linux C socket 编程之TCP

    推荐:http://www.cnblogs.com/tianshuai11/archive/2011/11/30/2477224.html

  9. 【Linux】Linux C socket 编程之UDP

    发送方: /* * File: main.c * Author: tianshuai * * Created on 2011年11月29日, 下午10:34 * * 主要实现:发送20个文本消息,然后 ...

随机推荐

  1. Git——Git常用命令速查表

  2. windows访问linux共享文件夹

    1.windows的网上邻居,是通过smb协议来共享信息的,如果需要给访问linux上的共享目录被windows访问到,需要linux有smb协议 sudo apt-get install samba ...

  3. iframe子页面获取父页面元素和window对象

    项目中发现要在iframe的弹框中获取父页面中的元素,我们可以按照如下代码操作:$(window.parent.document).find('selector').attr('XXX') 如果我们需 ...

  4. Solr产品化部署

    1.下载solr-6.4.1.tgz到任意目录 2.执行tar xzf solr-6.4.1.tgz solr-6.4.1/bin/install_solr_service.sh --strip-co ...

  5. Restful Framework (三)

    目录 一.版本 二.解析器 三.序列化 四.请求数据验证 一.版本 回到顶部 程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取. c ...

  6. mybatis官网学习

    javaType:一个 Java 类的完全限定名,或一个类型别名(参考上面内建类型别名 的列表) .如果你映射到一个 JavaBean,MyBatis 通常可以断定类型. 然而,如果你映射到的是 Ha ...

  7. angularJS的MVC的用法

    1.前端MVC: M:Model,数据库 V:HTML页面 C:Control控制器 比较很有名的前端MVC框架:ExtJs 2.angularJS的MVC框架搭建 index.html代码如下: & ...

  8. 这种文件别打开, 大小不足1KB, 却可以让你电脑瘫痪

    今年6月份,抖音表白代码火了,不足1kb的txt文件,玩出了新花样.可是你知道吗,这种非常“浪漫”的表白方式,其实存在着很大的风险,甚至会让你的电脑直接瘫痪. 首先,先说一下所谓的表白代码是怎么回事. ...

  9. CentOS7安装Pycharm后无法使用日常的快捷键

    1.在百度查了一圈,原来是vim在搞鬼 楼主在安装的时候,有另外添加了vim插件,所以ctrl +c之类的键都用不了,而且每次写py文件前都要先按insert键,真坑! 2.卸载pycharm里面的v ...

  10. KVM-克隆和快照管理

    kvm 虚拟机有两部分组成:img镜像文件和xml配置文件 /etc/libvirt/qemu #xml配置文件目录,存在虚拟机所有的详细信息 1.kvm虚拟机克隆 克隆命令 virt-clone - ...