程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C標准庫IO函數的錯誤識別

C標准庫IO函數的錯誤識別

編輯:關於C語言

 

errno全局變量

很多系統函數在錯誤返回時將錯誤原因記錄在libc定義的全局變量errno中,每種錯誤原因對應一個錯誤碼,請查閱errno(3)的Man Page了解各種錯誤碼,errno在頭文件errno.h中聲明,是一個整型變量,所有錯誤碼都是正整數。

如:當使用fopen打開文件失敗時,該函數返回NULL,而且同時將錯誤原因記錄在全局變量errno中。

 

如果在程序中打印錯誤信息時直接打印errno變量,打印出來的只是一個整數值,仍然看不出是什麼錯誤。比較好的辦法是用perror或strerror函數將errno解釋成字符串再打印。

perror函數

 

#include <stdio.h> 

 

void perror(const char *s); 

 

 

perror函數將錯誤信息打印到標准錯誤輸出,首先打印參數s所指的字符串,然後打印:號,然後根據當前errno的值打印錯誤原因。例如:

例perror

 

#include <stdio.h> 

#include <stdlib.h> 

 

int main(void) 

    FILE *fp = fopen("abcde", "r"); 

    if (fp == NULL) { 

        perror("Open file abcde"); 

        exit(1); 

    } 

    return 0; 

 

 

如果文件abcde不存在,fopen返回-1並設置errno為ENOENT,緊接著perror函數讀取errno的值,將ENOENT解釋成字符串No such file or directory並打印,最後打印的結果是Open file abcde: No such file or directory。雖然perror可以打印出錯誤原因,傳給perror的字符串參數仍然應該提供一些額外的信息,以便在看到錯誤信息時能夠很快定位是程序中哪裡出了錯,如果在程序中有很多個fopen調用,每個fopen打開不同的文件,那麼在每個fopen的錯誤處理中打印文件名就很有幫助。

 

如果把上面的程序改成這樣:

 

#include <stdio.h> 

#include <stdlib.h> 

#include <errno.h> 

 

int main(void) 

    FILE *fp = fopen("abcde", "r"); 

    if (fp == NULL) { 

        perror("Open file abcde"); 

        printf("errno: %d\n", errno); 

        exit(1); 

    } 

    return 0; 

 

 

則printf打印的錯誤號並不是fopen產生的錯誤號,而是perror產生的錯誤號。errno是一個全局變量,很多系統函數都會改變它,fopen函數Man Page中的ERRORS部分描述了它可能產生的錯誤碼,perror函數的Man Page中沒有ERRORS部分,說明它本身不產生錯誤碼,但它調用的其它函數也有可能改變errno變量。大多數系統函數都有一個Side Effect,就是有可能改變errno變量(當然也有少數例外,比如strcpy),所以一個系統函數錯誤返回後應該馬上檢查errno,在檢查errno之前不能再調用其它系統函數。

 

strerror函數

strerror函數可以根據錯誤號返回錯誤原因字符串。

 

#include <string.h> 

 

char *strerror(int errnum); 

 

 

返回值:錯誤碼errnum所對應的字符串

這個函數返回指向靜態內存的指針。以後學線程庫時我們會看到,有些函數的錯誤碼並不保存在errno中,而是通過返回值返回,就不能調用perror打印錯誤原因了,這時strerror就派上了用場:

fputs(strerror(n), stderr);

作者 kevinzhangyang

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved