可以编写一个用来调试的函数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的结果一样。