int func(){int bIsErrOccur = 0;//do something that might invoke errorsif(bIsErrOccur) //Stage 1: error occurredreturn -1; //Stage 2: generate error indicator//...return 0;}int main(void){if(func() != 0) //Stage 3: detect error{//Stage 4: handle error}//Stage 5: recover or abortreturn 0;}
if((p = malloc(100)) == NULL)//...if((c = getchar()) == EOF)//...if((ticks = clock()) < 0)//...
char *IntToAscii(int dwVal, char *pszRes, int dwRadix){if(NULL == pszRes)return "Arg2Null";if((dwRadix < 2) || (dwRadix > 36))return "Arg3OutOfRange";//...return pszRes;}
typedef enum{S_OK, //成功S_ERROR, //失敗(原因未明確),通用狀態S_NULL_POINTER, //入參指針為NULLS_ILLEGAL_PARAM, //參數值非法,通用S_OUT_OF_RANGE, //參數值越限S_MAX_STATUS //不可作為返回值狀態,僅作枚舉最值使用}FUNC_STATUS;((eRetCode) == S_OK ? : \((eRetCode) == S_ERROR ? : \((eRetCode) == S_NULL_POINTER ? : \((eRetCode) == S_ILLEGAL_PARAM ? : \((eRetCode) == S_OUT_OF_RANGE ? : \)))))
extern int errno;
extern int *__errno_location(void);
//調用庫函數if(返回錯誤值)//檢查errno
if (somecall() == -1){printf("somecall() failed\n");if(errno == ...) { ... }}
if (somecall() == -1){int dwErrSaved = errno;printf("somecall() failed\n");if(dwErrSaved == ...) { ... }}
char *strerror(int errnum);
void perror(const char *msg);
int main(int argc, char** argv){errno = 0;FILE *pFile = fopen(argv[1], "r");if(NULL == pFile){printf("Cannot open file '%s'(%s)!\n", argv[1], strerror(errno));perror("Open file failed");}else{printf("Open file '%s'(%s)!\n", argv[1], strerror(errno));perror("Open file");fclose(pFile);}return 0;}
[wangxiaoyuan_@localhost test1]$ ./GlbErr /sdb1/wangxiaoyuan/linux_test/test1/test.cOpen file '/sdb1/wangxiaoyuan/linux_test/test1/test.c'(Success)!Open file: Success[wangxiaoyuan_@localhost test1]$ ./GlbErr NonexistentFile.hCannot open file 'NonexistentFile.h'(No such file or directory)!Open file failed: No such file or directory[wangxiaoyuan_@localhost test1]$ ./GlbErr NonexistentFile.h > testOpen file failed: No such file or directory[wangxiaoyuan_@localhost test1]$ ./GlbErr NonexistentFile.h 2> testCannot open file 'NonexistentFile.h'(No such file or directory)!
int *_fpErrNo(void){static int dwLocalErrNo = 0;return &dwLocalErrNo;}//define other error macros...int Callee(void){ErrNo = 1;return -1;}int main(void){ErrNo = 0;if((-1 == Callee()) && (EOUTOFRANGE == ErrNo))printf("Callee failed(ErrNo:%d)!\n", ErrNo);return 0;}
double Division(double fDividend, double fDivisor){return fDividend/fDivisor;}int main(void){int dwFlag = 0;if(1 == dwFlag){RaiseException:printf("The divisor cannot be 0!\n");exit(1);}dwFlag = 1;double fDividend = 0.0, fDivisor = 0.0;printf("Enter the dividend: ");scanf("%lf", &fDividend);printf("Enter the divisor : ");scanf("%lf", &fDivisor);if(0 == fDivisor) //不太嚴謹的浮點數判0比較goto RaiseException;printf("The quotient is %.2lf\n", Division(fDividend, fDivisor));return 0;}
[]$ ./testEnter the dividend: 10Enter the divisor : 0The divisor cannot be 0![]$ ./testEnter the dividend: 10Enter the divisor : 2The quotient is 5.00雖然goto語句會破壞代碼結構性,但卻非常適用于集中錯誤處理。偽代碼示例如下:CallerFunc(){if((ret = CalleeFunc1()) < 0);goto ErrHandle;if((ret = CalleeFunc2()) < 0);goto ErrHandle;if((ret = CalleeFunc3()) < 0);goto ErrHandle;//...return;ErrHandle://Handle Error(e.g. printf)return;}
int setjmp(jmp_buf env);void longjmp(jmp_buf env,int val);
jmp_buf gJmpBuf;void Func1(){printf("Enter Func1\n");if(0)longjmp(gJmpBuf, 1);}void Func2(){printf("Enter Func2\n");if(0)longjmp(gJmpBuf, 2);}void Func3(){printf("Enter Func3\n");if(1)longjmp(gJmpBuf, 3);}int main(void){int dwJmpRet = setjmp(gJmpBuf);printf("dwJmpRet = %d\n", dwJmpRet);if(0 == dwJmpRet){Func1();Func2();Func3();}else{switch(dwJmpRet){case 1:printf("Jump back from Func1\n");break;case 2:printf("Jump back from Func2\n");break;case 3:printf("Jump back from Func3\n");break;default:printf("Unknown Func!\n");break;}}return 0;}
dwJmpRet = 0Enter Func1Enter Func2Enter Func3dwJmpRet = 3Jump back from Func3
jmp_buf gJmpBuf;void RaiseException(void){printf("Exception is raised: ");longjmp(gJmpBuf, 1); //throw,跳轉至異常處理代碼printf("This line should never get printed!\n");}double Division(double fDividend, double fDivisor){return fDividend/fDivisor;}int main(void){double fDividend = 0.0, fDivisor = 0.0;printf("Enter the dividend: ");scanf("%lf", &fDividend);printf("Enter the divisor : ");if(0 == setjmp(gJmpBuf)) //try塊{scanf("%lf", &fDivisor);if(0 == fDivisor) //也可將該判斷及RaiseException置于Division內RaiseException();printf("The quotient is %.2lf\n", Division(fDividend, fDivisor));}else //catch塊(異常處理代碼){printf("The divisor cannot be 0!\n");}return 0;}
Enter the dividend: 10Enter the divisor : 0Exception is raised: The divisor cannot be 0!
typedef void (*fpSigFunc)(int);fpSigFunc signal(int signo, fpSigFunc fpHandler);int raise(int signo);
void fphandler(int dwSigNo){printf("Exception is raised, dwSigNo=%d!\n", dwSigNo);}int main(void){if(SIG_ERR == signal(SIGFPE, fphandler)){fprintf(stderr, "Fail to set SIGFPE handler!\n");exit(EXIT_FAILURE);}double fDividend = 10.0, fDivisor = 0.0;if(0 == fDivisor){raise(SIGFPE);exit(EXIT_FAILURE);}printf("The quotient is %.2lf\n", fDividend/fDivisor);return 0;}
int main(void){if(SIG_ERR == signal(SIGFPE, fphandler)){fprintf(stderr, "Fail to set SIGFPE handler!\n");exit(EXIT_FAILURE);}int dwDividend = 10, dwDivisor = 0;double fQuotient = dwDividend/dwDivisor;printf("The quotient is %.2lf\n", fQuotient);return 0;}
jmp_buf gJmpBuf;void fphandler(int dwSigNo){printf("Exception is raised, dwSigNo=%d!\n", dwSigNo);longjmp(gJmpBuf, 1);}int main(void){if(SIG_ERR == signal(SIGFPE, SIG_DFL)){fprintf(stderr, "Fail to set SIGFPE handler!\n");exit(EXIT_FAILURE);}int dwDividend = 10, dwDivisor = 0;if(0 == setjmp(gJmpBuf)){double fQuotient = dwDividend/dwDivisor;printf("The quotient is %.2lf\n", fQuotient);}else{printf("The divisor cannot be 0!\n");}return 0;}
void exit(int status);void _Exit(int status);void _exit(int status);
int main(void){printf("Using exit...\n");printf("This is the content in buffer");exit(0);printf("This line will never be reached\n");}
Using exit...This is the content in buffer(結尾無換行符)
int main(void){printf("Using _exit...\n");printf("This is the content in buffer");fprintf(stdout, "Standard output stream");fprintf(stderr, "Standard error stream");//fflush(stdout);_exit(0);}
Using _exit...Standard error stream(結尾無換行符)
Using _exit...Standard error streamThis is the content in bufferStandard output stream(結尾無換行符)
int atexit(void (*func)(void));
double Division(double fDividend, double fDivisor){return fDividend/fDivisor;}void RaiseException1(void){printf("Exception is raised: \n");}void RaiseException2(void){printf("The divisor cannot be 0!\n");}int main(void){double fDividend = 0.0, fDivisor = 0.0;printf("Enter the dividend: ");scanf("%lf", &fDividend);printf("Enter the divisor : ");scanf("%lf", &fDivisor);if(0 == fDivisor){atexit(RaiseException2);atexit(RaiseException1);exit(EXIT_FAILURE);}printf("The quotient is %.2lf\n", Division(fDividend, fDivisor));return 0;}
Enter the dividend: 10Enter the divisor : 0Exception is raised:The divisor cannot be 0!
#include <stdlib.h>void abort(void);
void abort(void){raise(SIGABRT);exit(EXIT_FAILURE);}
extern void __assert((const char *, const char *, int, const char *));((void) ((expr) || \(__assert(
void __assert(const char *assertion, const char * filename,int linenumber, register const char * function){fprintf(stderr, " [%s(%d)%s] Assertion '%s' failed.\n",filename, linenumber,((function == NULL) ? "UnknownFunc" : function),assertion);abort();}
(fprintf(stderr, "[%s(%d)] Assertion '%s' failed.\n", \__FILE__, __LINE__,
char *Strcpy(char *pszDst, const char *pszSrc){char *pszDstOrig = pszDst;assert((pszDst != NULL) && (pszSrc != NULL));while((*pszDst++ = *pszSrc++) != '\0');return pszDstOrig;}FILE *OpenFile(const char *pszName, const char *pszMode){FILE *pFile = fopen(pszName, pszMode);assert(pFile != NULL);if(NULL == pFile)return NULL;//...return pFile;}
int main(void){int dwChg = 0;assert(dwChg = 1);if(0 == dwChg)printf("Assertion should be enabled!\n");return 0;}
pid_t Fork(void) //首字母大寫,以區分系統函數fork(){pid_t pid;if((pid = fork())<0){fprintf(stderr, "Fork error: %s\n", strerror(errno));exit(0);}return pid;}
int daemon_proc; /* set nonzero by daemon_init() */static void err_doit(int errnoflag, int level, const char * fmt, va_list ap){int errno_save, n;char buf[MAXLINE + 1];errno_save = errno; /* Value caller might want printed. */vsnprintf(buf, MAXLINE, fmt, ap);vsprintf(buf, fmt, ap); /* This is not safe */n = strlen(buf);if (errnoflag) {snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));}strcat(buf, "\n");if (daemon_proc) {syslog(level, buf);} else {fflush(stdout); /* In case stdout and stderr are the same */fputs(buf, stderr);fflush(stderr);}return;}void err_ret(const char * fmt, ...){va_list ap;va_start(ap, fmt);err_doit(1, LOG_INFO, fmt, ap);va_end(ap);return;}
作者:clover-toeic
原文:https://www.cnblogs.com/clover-toeic/p/3919857.html
飛機上一般是什么操作系統?
高速CAN、容錯CAN、LIN總線有什么區別?
大佬終于把鴻蒙OS講明白了,收藏了!