C語言錯誤處理



C語言本身並不直接支援錯誤處理,因為C語言中沒有可以防止錯誤或異常突然終止程式的關鍵字。但是,程式設計師可以使用其他函式進行錯誤處理。

您可以使用errno高效地處理C語言中的錯誤。此外,還可以使用其他函式進行錯誤處理,例如perror、strerror、ferrorclearerr

errno變數

C語言是一種系統程式語言。它以返回值的形式提供對底層的訪問。大多數C語言甚至Unix函式呼叫在發生任何錯誤時返回-1或NULL,並設定錯誤程式碼errno。它被設定為全域性變數,指示在任何函式呼叫期間發生錯誤。您可以在<error.h>標頭檔案中找到各種已定義的錯誤程式碼。

因此,C程式設計師可以檢查返回值,並根據返回值採取適當的操作。最好在程式初始化時將errno設定為0。值為0表示程式中沒有錯誤。

下表顯示了errno值及其關聯的錯誤訊息:

errno值 錯誤
1 操作不被允許
2 沒有這樣的檔案或目錄
3 沒有這樣的程序
4 系統呼叫中斷
5 I/O錯誤
6 沒有這樣的裝置或地址
7 引數列表太長
8 可執行檔案格式錯誤
9 錯誤的檔案編號
10 沒有子程序
11 請重試
12 記憶體不足
13 許可權被拒絕

示例

請看下面的例子:

#include <stdio.h>
#include <errno.h>

int main() {

   FILE* fp;

   // opening a file which does not exist
   fp = fopen("nosuchfile.txt", "r");
   printf("Value of errno: %d\n", errno);

   return 0;
}

輸出

它將產生以下輸出:

Value of errno: 2

C語言提供perror()和strerror()函式,可以用來顯示與errno相關的文字訊息。

perror()函式

顯示您傳遞給它的字串,後跟一個冒號、一個空格,然後是當前errno值的文字表示。

void perror(const char *str);

示例

在上面的例子中,“errno = 2”與訊息沒有這樣的檔案或目錄相關,可以使用perror()函式列印。

#include <stdio.h>
#include <errno.h>

int main(){

   FILE* fp;

   // opening a file which does not exist
   fp = fopen("nosuchfile.txt", "r");

   printf("Value of errno: %d\n", errno);
   perror("Error message:");

   return 0;
}

輸出

執行此程式碼時,將產生以下輸出:

Value of errno: 2
Error message: No such file or directory

strerror()函式

這將返回一個指向當前errno值文字表示的指標。

char *strerror(int errnum);

讓我們使用此函式顯示errno=2的文字表示:

示例

請看下面的例子:

#include <stdio.h>
#include <errno.h>

int main() {

   FILE* fp;

   // opening a file which does not exist
   fp = fopen("nosuchfile.txt", "r");

   printf("Value of errno: %d\n", errno);
   printf("The error message is : %s\n", strerror(errno));

   return 0;
}

輸出

Value of errno: 2
he error message is : No such file or directory

ferror()函式

此函式用於檢查檔案操作期間是否發生錯誤。

int ferror(FILE *stream);

示例

在這裡,我們嘗試從以“w”模式開啟的檔案中讀取。ferror()函式用於列印錯誤訊息。

#include <stdio.h>

int main(){

   FILE *fp;
   fp = fopen("test.txt","w");
   char ch = fgetc(fp);  // Trying to read data, from writable file
   if(ferror(fp)){
      printf("File is opened in writing mode! You cannot read data from it!");
   }
   fclose(fp);
   
   return(0);
}

輸出

執行程式碼並檢查其輸出:

File is opened in writing mode! You cannot read data from it!

clearerr()函式

clearerr()函式用於清除檔案流的EOF和錯誤指示符。

void clearerr(FILE *stream);

示例

請看下面的例子:

#include <stdio.h>

int main(){

   FILE *fp;
   fp = fopen("test.txt","w");

   char ch = fgetc(fp);  // Trying to read data, from writable file

   if(ferror(fp)){
      printf("File is opened in writing mode! You cannot read data from it!\n");
   }

   // Clears error-indicators from the file stream 
   // Subsequent ferror() doesn't show error
   clearerr(fp);

   if(ferror(fp)){
      printf("Error again in reading from file!");
   }
   fclose(fp);
   
   return(0);
}

除零錯誤

一個常見問題是,在除法運算時,程式設計師不檢查除數是否為零,最終導致執行時錯誤。

示例1

以下程式碼透過在除法之前檢查除數是否為零來修復此錯誤:

#include <stdio.h>
#include <stdlib.h>

int main() {
   int dividend = 20;
   int divisor = 0;
   int quotient;
 
   if( divisor == 0){
      fprintf(stderr, "Division by zero! Exiting...\n");
      exit(-1);
   }
   quotient = dividend / divisor;
   fprintf(stderr, "Value of quotient : %d\n", quotient );
   exit(0);
}

輸出

編譯並執行上述程式碼時,將產生以下結果:

Division by zero! Exiting...
Program Exit Status

通常的做法是在程式成功操作後退出時使用EXIT_SUCCESS值。這裡,EXIT_SUCCESS是一個宏,定義為0。

示例2

如果您的程式中存在錯誤條件並且您要退出,則應使用EXIT_FAILURE狀態退出,該狀態定義為“-1”。所以讓我們將上面的程式改寫如下:

#include <stdio.h>
#include <stdlib.h>

int main() {

   int dividend = 20;
   int divisor = 5;
   int quotient;

   if(divisor == 0) {
      fprintf(stderr, "Division by zero! Exiting...\n");
      exit(EXIT_FAILURE);
   }

   quotient = dividend / divisor;
   fprintf(stderr, "Value of quotient: %d\n", quotient );

   exit(EXIT_SUCCESS);
}

輸出

編譯並執行上述程式碼時,將產生以下結果:

Value of quotient: 4
廣告