【例20.14】演示使用errno函數的例子。
#include<stdio.h> #include<errno.h> #include<string.h> int main (void ) { FILE *fp ; char Line[100] ; fp=fopen ("f :\\ct4\\cfile.txt" ,"r" ); if (errno ) { printf ("\n 文件打不開!\n" ); return -1 ; } fgets (Line ,100 ,fp ); // 讀文件的一行信息 puts (Line ); // 顯示 fclose (fp ); // 關閉文件 getchar (); return 0 ; }
當文件不存在時,運行結果為:
文件打不開!
當文件存在時,運行結果為:
How are you ?
從運行結果看,程序好像很正常。其實,這不具備普遍性。很多庫函數,特別是那些與操作系統有關的庫函數,當它們執行失敗時會通過一個名為errno的全局變量,通知程序該函數調用失敗。
但在設計庫函數時,並沒有要求庫函數調用正確時,一定要設置errno為0,這時errno的值就可能是前一個調用失敗的庫函數設置的值。如果是這樣,就會給這種處理方式帶來錯誤。這裡之所以表現正常,是因為fopen函數的設計設置了errno的原因。
正確的做法是在調用庫函數時,首先檢查作為錯誤指示的返回值,確定程序執行已經失敗。然後再檢查errno,以便搞清出錯的原因。推薦的格式為:
// 調用庫函數 if (返回的錯誤值) // 檢查errno 得到錯誤類型
將上面的程序改為如下形式。
#include<stdio.h> #include<errno.h> #include<string.h> int main (void ) { FILE *fp ; char Line[100] ; fp=fopen ("f :\\ct4\\cfile.txt" ,"r" ); if (fp==NULL ) { printf ("%d %s\n" ,errno ,strerror (errno )); return -1 ; } fgets (Line ,100 ,fp ); // 讀文件的一行信息 puts (Line ); // 顯示 fclose (fp ); // 關閉文件 getchar (); return 0 ; }
當文件不存在時,運行結果為:
2 No such file or directory
當文件存在時,運行結果為:
How are you ?
程序中的strerror函數用來輸出用戶程序錯誤信息。它的定義在頭文件string.h中。
下面舉一個簡單的例子說明errno的使用方法。
【例20.15】演示在除法函數中使用errno函數的例子。
#include<stdio.h> #include<errno.h> #include<string.h> double pe (double ,double ); int main (void ) { double a ,b ,c ; printf (" 輸入實數a 和b 的值:" ); scanf ("%lf%lf" ,&a ,&b ); c=pe (a ,b ); if (c==0 ) { printf ("%d %s\n" ,errno ,strerror (errno )); return -1 ; } printf ("%lf/%lf=%lf\n" ,a ,b ,c ); return 0 ; } double pe (double a ,double b ) { if (b==0 ) { errno=1 ; return 0 ; }else{ return a/b ; } }
運行示例如下。
輸入實數a 和b 的值: 87.96 4.32 87.960000/4.320000=20.361111 輸入實數a 和b 的值: 5.2 0 1 Operation not permitted