三個(gè)必要的頭文件
#include <stdio.h>
#include <errno.h>
#include <string.h>
一個(gè)聲明
extern int errno;
四個(gè)重要函數(shù)
int ferror(FILE* stream);
int feof(FILE* stream);
char *strerror(int errnum);
void perror(const char *s);
以上是在錯(cuò)誤處理中常用的操作,前兩者是必要包含的,最后的函數(shù)則是酌情使用
ferror:
0值,如果沒有錯(cuò)誤則返回 0feof:
用于檢查是否到了文件尾,經(jīng)常用于文件的讀取工作,讀取到文件尾則返回非零值
input = fopen("file.in", "r");
while(!feof(input))
{
fscanf(input, "%s", str);
...
等同于
do{
rtn_value = fscanf(input, "%s", str);
...
}while(rtn_value != EOF);
strerror:
當(dāng)某個(gè)函數(shù)或者操作觸發(fā)了設(shè)置 errno 變量的時(shí)候,我們可以立即使用該函數(shù)進(jìn)行顯示輸出
strerror(errno);
輸出: Too many open files
perror:
與上方的函數(shù)相同,也是用來(lái)輸出錯(cuò)誤的,只不過(guò)它自動(dòng)使用 errno 變量,并且在自前方添加所傳入的參數(shù)以及一個(gè)冒號(hào)
perror("Now");
輸出: Now: Too many open files
同樣的,對(duì)于自己的錯(cuò)誤處理,可以設(shè)計(jì)一個(gè)小體系來(lái)滿足自我需求
通過(guò)返回值
/* fun.h */
void fun_error(size_t errnum);
size_t test_fun(int arg);
在此我們可以讓外界接觸不到真實(shí)的包含有錯(cuò)誤的數(shù)組或其他數(shù)據(jù)結(jié)構(gòu),而是將其放于.c文件中隱藏起來(lái),通過(guò)一個(gè)函數(shù)來(lái)進(jìn)行訪問(wèn)。
隱藏錯(cuò)誤實(shí)現(xiàn)
/* fun.c */
static const char * fun_err[] = { "Computing nagative!",
"Invalid argument",
"Bad result" };
size_t test_fun(int arg) { ... }
void fun_error(size_t errnum) { ... }
對(duì)于需要進(jìn)一步規(guī)格化的設(shè)計(jì)來(lái)說(shuō),可以使用 enum 或者 #define 來(lái)設(shè)定每個(gè)錯(cuò)誤返回值的名字
設(shè)定名字
/*fun.h*/
#define ERR_CMPUTING 0
#define ERR_INVARG 1
#define ERR_BADRLT 2
/* 或者 */
enum { ERR_COMPUTING = 0,
ERR_INVALIDARG,
ERR_BADRESULT };
如此我們便可以在函數(shù)中使用錯(cuò)誤的名字代號(hào),而不是去記下每個(gè)數(shù)字的含義。對(duì)此也可以不使用數(shù)組這個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)保存錯(cuò)誤信息,而采用 switch 在代碼中實(shí)現(xiàn)錯(cuò)誤的處理
switch錯(cuò)誤選擇·
/*fun.c*/
/*
static const char * fun_err[] = { "Computing nagative!",
"Invalid argument",
"Bad result" };
*/
...
void fun_error(size_t errnum)
{
switch(errnum)
{
case ERR_CMPUTING /*ERR_COMPUTING*/:
fprintf(stderr, "...");
break;
case ERR_INVARG /*ERR_INVALIDARG*/:
fprintf(stderr, "...");
break;
...
default :
...
}
return;
}
如此做的好處便是,不再需要去安排數(shù)組的個(gè)數(shù),而是直接在代碼中展示。并且可以加上一些預(yù)處理,來(lái)實(shí)現(xiàn)開關(guān)錯(cuò)誤顯示。
開關(guān)錯(cuò)誤
/* fun.c */
...
void fun_error(size_t errnum)
{
#if !defined(NOT_DEBUG)
switch(errnum)
{
...
}
#endif
return;
}