映月读书网 > 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的结果一样。