1、C语言的错误处理
其它编程语言中,例如,C++,Java,C#,Python等语言中,都可以使用try catch类似语法进行异常处理。C语言中没有异常机制,一般用返回值标识错误,判断返回值进行错误的处理。
返回值表示出错的常见情况可能如下:
1)如果函数返回值是int
,并且返回的数据不可能是负数,直接返回-1
表示出错,非负数代表正常返回数据。
2)如果函数返回值是int
,但返回的数据也可能是负数;返回0
代表正常,-1
代表出错。用指针类型的参数带出返回的数据。
3)如果函数返回值是指针类型,返回NULL
(0)代表出错,其他代表正常。
4)如果函数不需要考虑出错情况,可以用void
返回值。
2、错误异常处理函数及全局变量
C标准中,对于错误处理提供了一个全局变量和3个函数:
1)全局变量
errno:外部的全局变量,用于储存错误的编号。
2)异常错误处理函数
strerror()
,perror()
,printf()
都可以把错误的编号转换成错误的信息。
strerror():传入一个错误的编号,返回一个错误的信息
perror():打印当前的错误信息(自动查找errno得到的错误编号)
printf("%m"):打印当前错误信息(自动查找errno)
例如,
#include#include #include extern int errno ;int main (){ FILE * pf; int errnum; pf = fopen ("wonhero.txt", "rb"); if (pf == NULL) { errnum = errno; fprintf(stderr, "错误号: %d\n", errno); perror("通过 perror 输出错误"); fprintf(stderr, "打开文件错误: %s\n", strerror( errnum )); } else { fclose (pf); } return 0;}
3、程序退出状态值
通常情况下,程序成功执行完一个操作正常退出的时候会带有值 EXIT_SUCCESS
。在这里,EXIT_SUCCESS
是宏,它被定义为 0
。
如果程序中存在一种错误情况,当退出程序时,会带有状态值 EXIT_FAILURE
,被定义为 -1
。
例如,
#include#include main(){ int dividend = 20; int divisor = 5; int quotient; if( divisor == 0){ fprintf(stderr, "除数为 0 退出运行...\n"); exit(EXIT_FAILURE); } quotient = dividend / divisor; fprintf(stderr, "quotient 变量的值为: %d\n", quotient ); exit(EXIT_SUCCESS);}
4、日志记录
C语言中记录日志能帮助程序员在程序开发时调试、记录及监控数据。程序在正式运行时,也方便能过日志来排查问题。
#include#include #include #include enum {ERROR,WARNING,INFO,DEBUG};//宏定义形式#define LogRecord(_error_level,_fmt,_X...) \ do { \ time_t _current_time=time(NULL); \ char _file_name[256]="\0"; \ strftime(_file_name,sizeof(_file_name),"%Y-%m-%d_log_record.log",localtime(&_current_time)); \ FILE *_fp=NULL; \ _fp=fopen(_file_name,"a+"); \ if(_fp!=NULL) \ { \ char _time_str[32]; \ strftime(_time_str,sizeof(_time_str),"%Y-%m-%d %H:%M:%S",localtime(&_current_time)); \ if(_error_level==ERROR) \ { \ fprintf(_fp,"[%s]-[%s]-[%s]-[%d] :> "_fmt"\n",_time_str,"ERROR",__FILE__,__LINE__,##_X); \ } \ else if(_error_level==WARNING) \ { \ fprintf(_fp,"[%s]-[%s]-[%s]-[%d] :> "_fmt"\n",_time_str,"WARNING",__FILE__,__LINE__,##_X); \ } \ else if(_error_level==INFO) \ { \ fprintf(_fp,"[%s]-[%s]-[%s]-[%d] :> "_fmt"\n",_time_str,"INFO",__FILE__,__LINE__,##_X); \ } \ else if(_error_level==DEBUG) \ { \ fprintf(_fp,"[%s]-[%s]-[%s]-[%d] :> "_fmt"\n",_time_str,"DEBUG",__FILE__,__LINE__,##_X); \ } \ fclose(_fp); \ } \ }while(0);//函数形式void log_reocrd(int error_level, const char *format, ...){ va_list args; FILE *fp=NULL; char time_str[32]; char file_name[256]; va_start (args, format); time_t time_log = time(NULL); strftime(file_name,sizeof(file_name),"%Y-%m-%d_log_history.log",localtime(&time_log)); if((fp=fopen(file_name,"a+"))!=NULL) { strftime(time_str,sizeof(time_str),"%Y-%m-%d %H:%M:%S",localtime(&time_log)); if(error_level==(int)ERROR) { fprintf (fp, "[%s]-[%s]-[%s]-[%d] :> ",time_str,"ERROR",__FILE__,__LINE__); vfprintf (fp,format,args); fprintf (fp,"\n"); } else if(error_level==(int)WARNING) { fprintf (fp, "[%s]-[%s]-[%s]-[%d] :> ",time_str,"WARNINGs",__FILE__,__LINE__); vfprintf (fp,format,args); fprintf (fp,"\n"); } else if(error_level==(int)INFO) { fprintf (fp, "[%s]-[%s]-[%s]-[%d] :> ",time_str,"INFO",__FILE__,__LINE__); vfprintf (fp,format,args); fprintf (fp,"\n"); } else if(error_level==(int)DEBUG) { fprintf (fp, "[%s]-[%s]-[%s]-[%d] :> ",time_str,"DEBUG",__FILE__,__LINE__); vfprintf (fp,format,args); fprintf (fp,"\n"); } fclose(fp); } va_end (args);}int main(){ int i=10; double x=3.1415926; long long k=123144345; LogRecord(INFO,"i=%d",i) LogRecord(INFO,"x=%lf",x) LogRecord(INFO,"k=%lld",k) LogRecord(INFO,"wonhero") LogRecord(INFO,"www.wonhero.com",NULL) log_reocrd(INFO,"i=%d",i); log_reocrd(INFO,"x=%lf",x); log_reocrd(INFO,"k=%lld",k); log_reocrd(INFO,"wonhero"); log_reocrd(INFO,"www.wonhero.com",NULL); printf("%s","finish"); return 0;}