讀古今文學網 > C語言解惑 > 13.5 編寫error函數 >

13.5 編寫error函數

可以編寫一個用來調試的函數error。如果調試信息是送往屏幕,編寫方法與前面定義的DEBUG函數是一樣的,只是有人喜歡使用error做名字,有人喜歡用DEBUG做名字。

考慮到用戶有可能把輸出定向到某個文件,這就可能造成將程序所產生的錯誤信息也會按定向指定文件,顯然這不是所希望的結果。上面定義的DEBUG函數就會發生這種情況,而這裡定義error函數就增加了新的措施,從而避免發生這種情況。

利用標準庫提供的標準錯誤流stderr,就可以解決這個問題。送到標準錯誤流的信息不受輸入流重定向的影響,因此也就不會混入定向的文件中。即使標準輸出流被定向,送到stdeer的信息仍會顯示在電腦屏幕上。

這裡需要用到一個新的庫函數vfprintf,這個函數的原型如下:


int vfprintf
(FILE *stream
, char *format
, va_list param
);
  

功能:將格式化的數據輸出到指定的數據流中。

函數說明:vfprintf會根據參數format字符串來轉換並格式化數據,然後將結果輸出到參數stream指定的文件中,直到出現字符串結束符(『\0』)為止。關於參數format字符串的格式可參考printf函數。

返回值:成功則返回實際輸出的字符數,失敗則返回-1,錯誤原因存於errno中。

把stderr作為第一個參數即可達到要求。同理,使用fprintf時,也用stderr作為第一個參數。

error函數增加幾條輸出信息,突出的是error函數的輸出以及輸出的字符數。下面給出這個函數的定義。


#include<stdarg.h>
void error 
(const char *format
, ...
)
{
        int num
;
        va_list ap
;
        va_start
(ap
, format
);
        fprintf
(stderr
, \"error
:n\"
);          //
標記為error
函數輸出
        num=vfprintf
(stderr
,format
, ap
);
        va_end
(ap
);
        fprintf
(stderr
, \"num = %dn\"
, num
);     //
輸出打印字數
}
  

下面是使用與例13.4一樣的主程序,演示使用error函數的例子。

【例13.9】使用自己定義的error函數的例子。


#include<stdio.h>
//
將error
函數的定義拷貝到此處
//
主程序
int main
(void
)
{
      int data[3][3]
, *p
;
      int sum=0
, i=0
, j=0
;
      p=&data[0][0]
;
      for 
( i=0
; i<9
; i++
)
        *
(p+i
)=10+i
;
      for 
( i=0
; i<3
; i++
)
      {
            for 
( j=0
; j<3
; j++
)
            {
                    sum = sum + data[i][j]
;
                    error 
( \"date[%d][%d] = %d \" 
, i
, j
,data[i][j] 
);
            }
              printf 
(\"n\"
);
      }
      printf
(\"sum = %dn\"
, sum
);
      return 0
;
}
  

將下面的輸出結果與例13.4對照,顯然只是多一些信息而已。


error
:
date[0][0] = 10 num = 16
error
:
date[0][1] = 11 num = 16
error
:
date[0][2] = 12 num = 16
error
:
date[1][0] = 13 num = 16
error
:
date[1][1] = 14 num = 16
error
:
date[1][2] = 15 num = 16
error
:
date[2][0] = 16 num = 16
error
:
date[2][1] = 17 num = 16
error
:
date[2][2] = 18 num = 16
sum = 126
  

可以為error函數增加一個參數,將原型聲明為如下形式:


void error 
( int n
, const char *format
, 
…)
  

定義一個整型全局常量on_off,當它為0時,error函數不起作用(與空語句等效),當它為非0值時,error函數有效。下面的例子中,定義為0,即


const int on_off  = 0
;
  

【例13.10】為error函數增加開關的例子。


#include<stdio.h>
#include<stdarg.h>
void error 
(int on_of
, const char *format
, 
…)
{
       int num
;
       if 
(on_of 
!= 0
)                    //
判斷是否使用error 
函數
       { //on_of
等於零時不使用error 
函數,非零則使用
          va_list ap
;
          va_start
(ap
, format
);
          fprintf
(stderr
, \"error
:n\"
);          //
標記為error
函數輸出
          num=vfprintf
(stderr
,format
, ap
);
          va_end
(ap
);
          fprintf
(stderr
, \"num = %dn\"
, num
);     //
輸出打印字數
       }
}
int main
(void
)
{
     int data[3][3]
, *p
;
     int sum=0
, i=0
, j=0
;
     const int on_of = 0
;  //
非0
時開關有效
     p=&data[0][0]
;
     for 
( i=0
; i<9
; i++
)
       *
(p+i
)=10+i
;
     for 
( i=0
; i<3
; i++
)
     {
           for 
( j=0
; j<3
; j++
)
            {
                   sum = sum + data[i][j]
;
                   error 
(on_of
, \"date[%d][%d] = %d \" 
, i
, j
,data[i][j] 
);
           }
            error 
(on_of
, \"n\" 
);
     }
    printf
(\"sum = %dn\"
, sum
);
    return 0
;
}
 

on_off為零,程序輸出結果為:


sum = 126
  

on_off非零時,程序輸出結果與例13.9的結果一樣。