在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ C/ 0x0B-C語言錯誤處理
0x0E-單線程備份(下)
0x11-套接字編程-1
0x05-C語言指針:(Volume-1)
0x13-套接字編程-HTTP服務器(1)
0x0C-開始行動
C 語言進階
第一部分
0x05-C語言指針(Volume-2)
0x08-C語言效率(下)
0x07-C語言效率(上)
0x04 C代碼規(guī)范
0x0F-多線程備份
0x05-C語言變量
第四部分
0x16-套接字編程-HTTP服務器(4)
0x0D-單線程備份(上)
總結(jié)
0x01-C語言序言
0x15-套接字編程-HTTP服務器(3)
0x14-套接字編程-HTTP服務器(2)
0x17-套接字編程-HTTP服務器(5)
第三部分
我的C語言
0x06-C語言預處理器
0x09-未曾領(lǐng)略的新風景
0x0A-C線程和Glib的視角
第二部分
0x10-網(wǎng)絡(luò)的世界
0x12-套接字編程-2
0x03-C代碼
0x0B-C語言錯誤處理

0x0B-C語言錯誤處理

0x0B-C語言錯誤處理

  • 三個必要的頭文件

      #include <stdio.h>
      #include <errno.h>
      #include <string.h>
  • 一個聲明

      extern int errno;
  • 四個重要函數(shù)

      int ferror(FILE* stream);
      int feof(FILE* stream);
      char *strerror(int errnum);
      void perror(const char *s);
  • 以上是在錯誤處理中常用的操作,前兩者是必要包含的,最后的函數(shù)則是酌情使用

    1. ferror
      • 檢查流中是否有錯誤,如果有則返回一個非0值,如果沒有錯誤則返回 0
    2. feof

      • 用于檢查是否到了文件尾,經(jīng)常用于文件的讀取工作,讀取到文件尾則返回非零值

              input = fopen("file.in", "r");
              while(!feof(input))
              {
                  fscanf(input, "%s", str);
                  ...
              等同于
              do{
                  rtn_value = fscanf(input, "%s", str);
                  ...
              }while(rtn_value != EOF);
    3. strerror

      • 當某個函數(shù)或者操作觸發(fā)了設(shè)置 errno 變量的時候,我們可以立即使用該函數(shù)進行顯示輸出

              strerror(errno);
              輸出: Too many open files
    4. perror

      • 與上方的函數(shù)相同,也是用來輸出錯誤的,只不過它自動使用 errno 變量,并且在自前方添加所傳入的參數(shù)以及一個冒號

              perror("Now");
              輸出: Now: Too many open files 
  • 同樣的,對于自己的錯誤處理,可以設(shè)計一個小體系來滿足自我需求

    • 通過返回值

          /* fun.h */
          void   fun_error(size_t errnum);
          size_t test_fun(int arg);

      在此我們可以讓外界接觸不到真實的包含有錯誤的數(shù)組或其他數(shù)據(jù)結(jié)構(gòu),而是將其放于.c文件中隱藏起來,通過一個函數(shù)來進行訪問。

    • 隱藏錯誤實現(xiàn)

          /* fun.c */
          static const char * fun_err[] = { "Computing nagative!",
                                              "Invalid argument",
                                              "Bad result" };
          size_t test_fun(int arg) { ... }
          void   fun_error(size_t errnum) { ... }

      對于需要進一步規(guī)格化的設(shè)計來說,可以使用 enum 或者 #define 來設(shè)定每個錯誤返回值的名字

    • 設(shè)定名字

          /*fun.h*/
          #define ERR_CMPUTING 0
          #define ERR_INVARG   1
          #define ERR_BADRLT   2
          /* 或者 */
          enum { ERR_COMPUTING = 0,
                  ERR_INVALIDARG,
                  ERR_BADRESULT };

      如此我們便可以在函數(shù)中使用錯誤的名字代號,而不是去記下每個數(shù)字的含義。對此也可以不使用數(shù)組這個數(shù)據(jù)結(jié)構(gòu)來保存錯誤信息,而采用 switch 在代碼中實現(xiàn)錯誤的處理

    • switch錯誤選擇·

          /*fun.c*/
          /*
          static const char * fun_err[] = { "Computing nagative!",
                                              "Invalid argument",
                                              "Bad result" };
          */
          ...
          void fun_error(size_t errnum)
          {
              switch(errnum)
              {
                  case ERR_CMPUTING /*ERR_COMPUTING*/:
                      fprintf(stderr, "...");
                      break;
                  case ERR_INVARG /*ERR_INVALIDARG*/:
                      fprintf(stderr, "...");
                      break;
                  ...
                  default :
                  ...
              }
              return;
          }

      如此做的好處便是,不再需要去安排數(shù)組的個數(shù),而是直接在代碼中展示。并且可以加上一些預處理,來實現(xiàn)開關(guān)錯誤顯示。

    • 開關(guān)錯誤

          /* fun.c */
          ...
          void fun_error(size_t errnum)
          {
          #if !defined(NOT_DEBUG)
              switch(errnum)
              {
                  ...
              }
          #endif
              return;
          }
    • 慎重使用
      • 在我設(shè)計程序的過程中,盡量讓錯誤提示減少,或者說用戶不應該接觸到錯誤以及處理錯誤,所以當一個程序沒有必要提供給用戶錯誤信息的時候,才是真正的完整程序,至于程序失敗那又是量一種境況,例如備份程序可能由于文件的屬性,而復制失敗,這是不可避免的,此時將失敗信息寫入文檔,呈現(xiàn)給用戶即可。