• 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头文件中;

    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 ", strerror(errno)); //转换错误码为对应的错误信息

      exit(1);

     }

     perror("perror");

     errno = 13;

     printf("strerror: %s ", 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

     

    <assert.h>中支持assert()函数,注意,assert()检查发现条件不成立时调用abort()终止程序执行,应用程序没有机会做清除工作。assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向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 ",strerror(errno));  
    14. exit(1);  
    15. }  
    16. perror("perror");  
    17. errno=13;  
    18. printf("strerror:%s ",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得到的一个信息)

     

     

     

     

     

     

     

     

     

     

     

     

    关于errnoperror,strerror函数

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

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

     

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

    char *strerror(int errnum);

    它返回errnum的值所对应的错误提示信息,例如errnum等于12的话,它就会返回"Cannot allocate memory"

    void  perror(const char *s);

    它先打印s指向的字符串,然后输出当前errno所对应的错误提示信息,例如当前errno若为12,调用perror("ABC"),会输出"ABC: Cannot allocate memory"

     

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

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

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

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

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

     

     

     

     

    perror函数和strerror函数的区别

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

          file descriptor 0standard 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手册,

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

                    exit(1);
    

            }
    

            perror("perror");
    

            printf("fork error:%s
    ",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
    

       

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    图像连通域标记算法研究
    介绍给大家学习Silverlight的网址!
    (1)Silverlight开发工具Microsoft Expression Blend 2 之“Hello SilverLight”
    (4)Silverlight开发工具Microsoft Expression Blend 2 之“Combine切割组合效果”
    (3下)Silverlight开发工具Microsoft Expression Blend 2 之“States和Object面板简单“按钮””
    (2)Silverlight开发工具Microsoft Expression Blend 2 之“左侧ToolBox”
    SilverLight 2正式版已经发布,Silverlight Toolkit即将和大家见面
    什么是RIA??未来发展方向!
    Microsoft SQL Server Database Publishing Wizard 使用
    (3上)Silverlight开发工具Microsoft Expression Blend 2 之“States和Object面板简单“按钮””
  • 原文地址:https://www.cnblogs.com/timssd/p/4109415.html
Copyright © 2020-2023  润新知