c/c++的异常统一处理
来源:互联网 发布:有点儿意思 软件下载 编辑:程序博客网 时间:2024/04/30 21:22
今天看HTK代码,发现里面的错误处理机制很好,所以自己在这里总结一下。如何将某些类型的错误集中起来统一处理,使得程序易于维护和具有更好的可读性。
这里假设有这样一个故事,有个美女征婚,理想中的男人如果要表白成功,需要具备6个条件:玫瑰(Rose),戒指(Ring),宝马(BWM),高(Tall),富(Rich),帅(Handsome)。(好吧,我承认这个故事很低俗,但是实在想不出其它例子来比喻了,将就着看吧,-_-)。如果少了一个条件,sorry,美女要抛出异常了。但是现在求婚的人太多,美女无暇顾及,所以决定先请人把关,再根据把关人反馈的结果统一处理。好了,先看C语言如何处理:
C语言错误统一处理
1 #include <stdio.h> 2 #include <memory.h> 3 #include <stdarg.h> 4 #define COUNT 6 5 static char *pall[]={"Ring", "Rose", "BMW", "Tall", "Rich", "Handsome"}; 6 7 8 typedef struct _Condition { 9 char *pgift[COUNT];10 int ngift;11 }Condition;//存储个人条件的结构体12 static void Select(const Condition *con);13 static void Herror(int ntype, char *str, ...);14 int main(int argc, char **argv)15 {16 Condition A,B,C;17 memset(A.pgift, 0, COUNT);18 memset(B.pgift, 0, COUNT);19 memset(C.pgift, 0, COUNT);20 A.pgift[1]=pall[1]; A.ngift=1;//A->Rose21 B.pgift[0]=pall[0]; B.pgift[5]=pall[5]; B.ngift=2;//B->Ring,Handsome22 C.pgift[1]=pall[1]; C.pgift[2]=pall[2]; C.pgift[4]=pall[4]; C.ngift=3;//C->Rose,BMW,Rich23 24 Select(&A);25 Select(&B);26 Select(&C);27 return 0;28 }29 /*****************************************30 *根据条件考虑每个人,并调用错误统一处理函数31 ******************************************/32 static void Select(const Condition *con)33 {34 if(con==NULL)35 return;36 switch(con->ngift)37 {38 case 0:39 break;40 case 1:41 Herror(1, "fail:only have %s", con->pgift[1]);42 break;43 case 2:44 Herror(2, "fail:only have %s,%s", con->pgift[0], con->pgift[5]);45 break;46 case 3:47 Herror(3, "fail:only have %s,%s,%s", con->pgift[1], con->pgift[2], con->pgift[4]);48 break;49 default:50 break;51 }52 }53 /********************************************54 * 统一处理55 * *****************************************/56 static void Herror(int ntype, char *str, ...)57 {58 va_list parg;59 FILE *f = stdout;60 va_start(parg, str);//获取指向可变参数的第一个参数的指针61 printf("\n---------Result--------\n");62 if(ntype < 3)63 printf("pass over:");64 else if(ntype < 5)65 printf("just so so:");66 else67 printf("wait and see:");68 vfprintf(f, str, parg);//输出结果69 printf("\n----------over---------\n");70 va_end(parg);//关闭指针71 fflush(f); 72 }
结构体中的ngift表示男人征婚准备的礼物数量。32行的select函数所做的工作就是把关,考擦每个男人的条件,对于不符合美女要求的,统一把把关结果反馈给Herror函数,这里Herror做的事情就是美女根据反馈结果下结论:ngift<3的直接pass掉(这美女有点物质,哈哈),介于3与5之间的她觉得一般般,只有大于5时,她决定再看看。这就完成了错误的处理过程。
值得说一下的是,Herror的最后参数是一个可变形参,所以具有更大的灵活性,便于程序的扩展。其中可变形参的获取用到了va_start和va_end宏,这个宏在标准库<stdarg.h>中定义。详细的使用说明可以去网上搜一下。
C++的统一异常处理
C++提供了异常处理的一个类:exception。为了解决我们自己碰到的异常,只需要继承这个类,并重载或自定义一些错误处理函数即可实现。同样是上面的列子,我们改动一下:
1 #include <iostream> 2 #include <cstdlib> 3 using namespace std; 4 #define COUNT 6 5 static char *pall[]={"Ring", "Rose", "BMW", "Tall", "Rich", "Handsome"}; 6 7 typedef struct _Condition { 8 char *pgift[COUNT]; 9 int ngift; 10 }Condition; 11 12 class MyException:public exception 13 { 14 public: 15 MyException():m_ntype(-1),m_str(NULL) {} 16 MyException(int n, char *p):m_ntype(n),m_str(p) {} 17 char* Deal() const throw(); 18 ~MyException() 19 { 20 if(m_str) 21 { 22 delete m_str; 23 m_str = NULL; 24 } 25 } 26 private: 27 int m_ntype; 28 char *m_str; 29 }; 30 static void Select(const Condition *con); 31 32 int main(int argc, char **argv) 33 { 34 Condition A,B,C; 35 Condition *pcon[3]; 36 memset(A.pgift, 0, COUNT); 37 memset(B.pgift, 0, COUNT); 38 memset(C.pgift, 0, COUNT); 39 A.pgift[1]=pall[1]; A.ngift=1;//A->Rose 40 B.pgift[0]=pall[0]; B.pgift[5]=pall[5]; B.ngift=2;//B->Ring,Handsome 41 C.pgift[1]=pall[1]; C.pgift[2]=pall[2]; C.pgift[4]=pall[4]; C.ngift=3;//C->Rose,BMW,Rich 42 pcon[0] = &A; pcon[1] = &B; pcon[2] = &C; 43 44 for (int i=0; i<3; i++) 45 { 46 try 47 { 48 Select(pcon[i]); 49 } 50 catch (MyException &e) 51 { 52 char *ptemp; 53 ptemp = e.Deal(); 54 if (ptemp!=NULL) 55 { 56 printf("\n---------Result--------\n"); 57 cout<<ptemp<<endl; 58 printf("\n----------over---------\n"); 59 delete ptemp; 60 } 61 } 62 } 63 return 0; 64 } 65 /***************************************** 66 *根据条件考虑每个人,并调用错误统一处理函数 67 ******************************************/ 68 static void Select(const Condition *con) 69 { 70 char *presult; 71 if(con==NULL) 72 return; 73 if (NULL == (presult = new char[1024])) 74 { 75 exit(1); 76 } 77 switch(con->ngift) 78 { 79 case 0: 80 break; 81 case 1: 82 sprintf(presult,"fail:only have %s",con->pgift[1]); 83 throw MyException(1, presult); 84 break; 85 case 2: 86 sprintf(presult,"fail:only have %s,%s", con->pgift[0], con->pgift[5]); 87 throw MyException(2, presult); 88 break; 89 case 3: 90 sprintf(presult,"fail:only have %s,%s,%s",con->pgift[1], con->pgift[2], con->pgift[4]); 91 throw MyException(3, presult); 92 break; 93 default: 94 break; 95 } 96 } 97 char* MyException::Deal() const throw() 98 { 99 char *pstr = new char[1024];100 if (pstr == NULL)101 return NULL;102 if(m_ntype < 3)103 sprintf(pstr,"pass over:%s",m_str);104 else if(m_ntype < 5)105 sprintf(pstr,"just so so:%s",m_str);106 else107 sprintf(pstr,"wait and see:",m_str);108 return pstr;109 }
利用C++的try/catch/throw框架即可捕获异常,在把关的select函数中,我们有自定义的异常类MyException对象,将相关信息写进类中,然后抛出。在catch中捕获以后,调用类的Deal函数对异常进行统一处理。如果以后美女的想法改变,只有达到了5项条件的才算正常,那我们只需要修改Deal函数就可以了。
- c/c++的异常统一处理
- C#_WinForm 统一捕获未处理的异常
- 统一的处理异常
- 异常的统一处理
- 统一异常的处理
- 统一的异常处理
- 统一处理jersey的异常
- springMVC的统一异常处理
- springmvc统一的异常处理
- C语言的异常处理
- C语言的异常处理
- C语言的异常处理
- c的异常处理学习
- C++&Qt的异常处理
- 异常处理(二、C语言的异常处理)
- resteasy 统一的异常处理handler
- Jersey框架的统一异常处理机制
- Spring MVC的异常统一处理方法
- 多进程遍历目录并查找文件
- 练手系列(链表)
- 利用sort对数组进行自定义排序
- oracle 查询当前数据库database,初始新建用户system用户名无法连接db,没开锁;新建用户和密码--授权
- 尾递归和编译器优化
- c/c++的异常统一处理
- c和c++中const的区别
- 求所有最大公共子序列的算法实现
- 图论:最短路径搜索--Dijkstra算法(c代码实现)
- 致青春---关于工作生活的一点感想
- 电子陀螺仪的角度获取测试
- 1.2 通往实用函数编程之路
- 电子陀螺仪的随机误差补偿---平稳性检验
- win32下的双缓冲绘图技术