
- C程式設計教程
- C語言 - 首頁
- C語言基礎
- C語言 - 概述
- C語言 - 特性
- C語言 - 歷史
- C語言 - 環境搭建
- C語言 - 程式結構
- C語言 - Hello World
- C語言 - 編譯過程
- C語言 - 註釋
- C語言 - 詞法單元
- C語言 - 關鍵字
- C語言 - 識別符號
- C語言 - 使用者輸入
- C語言 - 基本語法
- C語言 - 資料型別
- C語言 - 變數
- C語言 - 整數提升
- C語言 - 型別轉換
- C語言 - 型別強制轉換
- C語言 - 布林值
- C語言中的常量和字面量
- C語言 - 常量
- C語言 - 字面量
- C語言 - 轉義序列
- C語言 - 格式說明符
- C語言中的運算子
- C語言 - 運算子
- C語言 - 算術運算子
- C語言 - 關係運算符
- C語言 - 邏輯運算子
- C語言 - 位運算子
- C語言 - 賦值運算子
- C語言 - 一元運算子
- C語言 - 自增和自減運算子
- C語言 - 三元運算子
- C語言 - sizeof 運算子
- C語言 - 運算子優先順序
- C語言 - 其他運算子
- C語言中的決策語句
- C語言 - 決策語句
- C語言 - if 語句
- C語言 - if...else 語句
- C語言 - 巢狀 if 語句
- C語言 - switch 語句
- C語言 - 巢狀 switch 語句
- C語言中的迴圈
- C語言 - 迴圈
- C語言 - while 迴圈
- C語言 - for 迴圈
- C語言 - do...while 迴圈
- C語言 - 巢狀迴圈
- C語言 - 無限迴圈
- C語言 - break 語句
- C語言 - continue 語句
- C語言 - goto 語句
- C語言中的函式
- C語言 - 函式
- C語言 - 主函式
- C語言 - 按值呼叫函式
- C語言 - 按引用呼叫函式
- C語言 - 巢狀函式
- C語言 - 變參函式
- C語言 - 使用者自定義函式
- C語言 - 回撥函式
- C語言 - 返回語句
- C語言 - 遞迴
- C語言中的作用域規則
- C語言 - 作用域規則
- C語言 - 靜態變數
- C語言 - 全域性變數
- C語言中的陣列
- C語言 - 陣列
- C語言 - 陣列的特性
- C語言 - 多維陣列
- C語言 - 將陣列傳遞給函式
- C語言 - 從函式返回陣列
- C語言 - 變長陣列
- C語言中的指標
- C語言 - 指標
- C語言 - 指標和陣列
- C語言 - 指標的應用
- C語言 - 指標運算
- C語言 - 指標陣列
- C語言 - 指向指標的指標
- C語言 - 將指標傳遞給函式
- C語言 - 從函式返回指標
- C語言 - 函式指標
- C語言 - 指向陣列的指標
- C語言 - 指向結構體的指標
- C語言 - 指標鏈
- C語言 - 指標與陣列
- C語言 - 字元指標和函式
- C語言 - NULL 指標
- C語言 - void 指標
- C語言 - 懸空指標
- C語言 - 解引用指標
- C語言 - 近、遠和巨大指標
- C語言 - 指標陣列的初始化
- C語言 - 指標與多維陣列
- C語言中的字串
- C語言 - 字串
- C語言 - 字串陣列
- C語言 - 特殊字元
- C語言結構體和聯合體
- C語言 - 結構體
- C語言 - 結構體和函式
- C語言 - 結構體陣列
- C語言 - 自引用結構體
- C語言 - 查詢表
- C語言 - 點(.)運算子
- C語言 - 列舉(enum)
- C語言 - 結構體填充和打包
- C語言 - 巢狀結構體
- C語言 - 匿名結構體和聯合體
- C語言 - 聯合體
- C語言 - 位域
- C語言 - typedef
- C語言中的檔案處理
- C語言 - 輸入輸出
- C語言 - 檔案I/O (檔案處理)
- C語言預處理器
- C語言 - 預處理器
- C語言 - 預處理指令
- C語言 - 預處理器運算子
- C語言 - 宏
- C語言 - 標頭檔案
- C語言中的記憶體管理
- C語言 - 記憶體管理
- C語言 - 記憶體地址
- C語言 - 儲存類別
- 其他主題
- C語言 - 錯誤處理
- C語言 - 可變引數
- C語言 - 命令執行
- C語言 - 數學函式
- C語言 - static 關鍵字
- C語言 - 隨機數生成
- C語言 - 命令列引數
- C程式設計資源
- C語言 - 問答
- C語言 - 快速指南
- C語言 - 速查表
- C語言 - 有用資源
- C語言 - 討論
C語言錯誤處理
C語言本身並不直接支援錯誤處理,因為C語言中沒有可以防止錯誤或異常突然終止程式的關鍵字。但是,程式設計師可以使用其他函式進行錯誤處理。
您可以使用errno高效地處理C語言中的錯誤。此外,還可以使用其他函式進行錯誤處理,例如perror、strerror、ferror和clearerr。
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