strerror和perror函数详解
生活随笔
收集整理的這篇文章主要介紹了
strerror和perror函数详解
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
/*#include <string.h>
char *strerror(int errnum);
它返回errnum的值所對應的錯誤提示信息,例如errnum等于12的話,它就會返回"Cannot allocate memory"。
測試程序:*/
#include <stdio.h>
#include <string.h>
#include <errno.h>int main(void)
{int fd = 10;int ret;ret = close(fd);if(ret == -1)//fprintf(stderr, "close error with msg is: %s\n",strerror(errno));這兩行輸出的結果都是一樣的printf("close error with msg is: %s\n",strerror(errno));return 0;
}#include <stdio.h>
#include <string.h>
#include <errno.h>
#include<stdlib.h>
int main(void)
{ extern int errno;int fd = 10;int ret;ret = close(fd);if(ret == -1)printf("errno=%d\n",errno);char * mesg = strerror(errno);printf("Mesg:%s\n",mesg);exit(0);
}
/*[root@linux untitled folder 2]# gcc strerror1.c
[root@linux untitled folder 2]# ./a.out
errno=9
Mesg:Bad file descriptor
[root@linux untitled folder 2]#
*/
#include <stdio.h> int main(void) {int fd = 10;int ret;ret = close(fd);if(ret == -1)perror("close error");return 0; } /*[root@linux untitled folder 2]# gcc perror.c [root@linux untitled folder 2]# ./a.out close error: Bad file descriptor*/ //函數(shù)原型為void perror(const char *s); ?
#include <stdio.h> int main(void) {int fd = 10;int ret;ret = close(fd);if(ret == -1)perror("close error");return 0; } /*[root@linux untitled folder 2]# gcc perror.c [root@linux untitled folder 2]# ./a.out close error: Bad file descriptor*/ //函數(shù)原型為void perror(const char *s); ?
?
在linux編程中,strerror()是個好東東,因為一個孤零零的errno看不出個所以然,然而strerror()返回的錯誤描述已經(jīng)給我們解決問題提供了80%的成功率。但從安全性的角度來講,strerror_r是更好的選擇,因為: #include <string.h> char *strerror(int errnum); int strerror_r(int errnum, char *buf, size_t n);說明,對于函數(shù)strerror_r,第一個參數(shù)errnum是錯誤代碼,第二個參數(shù)buf是用戶提供的存儲錯誤描述的緩存,第三個參數(shù)n是緩存的大小。 1,在系統(tǒng)編程中錯誤通常通過函數(shù)返回值來表示,并通過特殊變量errno來描述。errno這個全局變量在<errno.h>頭文件中聲明如下:extern int errno;errno是一個由POSIX和ISO C標準定義的符號,看(用)起來就好像是一個整形變量。當系統(tǒng)調用或庫函數(shù)發(fā)生錯誤的時候,比如以只讀方式打開一個不存在的文件時,它的值將會被改變,根據(jù)errno值的不同,我們就可以知道自己的程序發(fā)生了什么錯誤,然后進行相應的處理。為什么,要強調errno看起來好像是一個整形變量呢?因為有的標準(如ISO C)只規(guī)定了errno的作用,而沒有規(guī)定它的實現(xiàn)方式,它可能被定義成一個變量,也有可能被定義成一個宏,這個具體要看編譯器自己的實現(xiàn)。早些時候,POSIX.1曾把errno定義成extern int errno這種形式,但現(xiàn)在這種方式比較少見了。因為以這種形式來實現(xiàn)errno,在多線程環(huán)境下errno變量是被多個線程共享的,這樣可能線程A發(fā)生某些錯誤改變了errno的值,線程B雖然沒有發(fā)生任何錯誤,但是當它檢測errno的值的時候,線程B會以為自己發(fā)生了錯誤。所以現(xiàn)在errno在Linux中被實現(xiàn)成extern int * __errno_location(void): #define errno (*__errno_location()),這樣每個線程都有自己的errno,不會再發(fā)生混亂了。關于errno有三點需要特別注意:1、如果系統(tǒng)調用或庫函數(shù)正確執(zhí)行的話,errno的值是不會被清零(置0,注意這里是不會被清零,不是不會被改變)的,假若執(zhí)行函數(shù)A的時候發(fā)生了錯誤errno被改變,接下來直接執(zhí)行函數(shù)B,如果函數(shù)B正確執(zhí)行的話,errno還保留函數(shù)A發(fā)生錯誤時被設置的值。所以,在利用errno之前,最好先對函數(shù)的返回值進行判斷,看是否發(fā)生了錯誤,返回值錯誤再利用errno判斷時哪里發(fā)生了錯誤。所以如果一個函數(shù)無法從返回值上判斷正誤,而只能通過errno來判斷出錯,那你在調用它之前必須手動將errno清零!2、系統(tǒng)調用或庫函數(shù)正確執(zhí)行,并不保證errno的值不會被改變!3、任何錯誤號(即發(fā)生錯誤時errno的取值)都是非0的。綜上所述,當需要用errno來判斷函數(shù)是否正確執(zhí)行的時候,最好先將errno清零,函數(shù)執(zhí)行結束時,通過其返回值判斷函數(shù)是否正確執(zhí)行,若沒有正確執(zhí)行,再根據(jù)errno判斷時哪里發(fā)生了錯誤。 也可以用這個函數(shù) #include <stdio.h> 函數(shù)原型為void perror(const char *s);?
轉載于:https://www.cnblogs.com/leijiangtao/p/4110856.html
總結
以上是生活随笔為你收集整理的strerror和perror函数详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《BI那点儿事》Microsoft 线性
- 下一篇: #if defined 和 #if !