Linux下參數處理函數–getopt函數族

來源:互聯網
上載者:User

Linux下開發C程式,甚至是GUI程式,都可能需要處理複雜的命令列參數。健全、可靠的複雜命令列參數處理機制,可使程式方便使用,也更顯專業。Linux下幾乎所有的命令都提供了參數處理機制,包括短選項和長選項。

  POSIX標準中對程式名、參數作了如下相關約定:
    * 程式名不宜少於2個字元且不多於9個字元;
    * 程式名應只包含小寫字母和阿拉伯數字;
    * 選項名應該是單字元活單數字,且以短橫‘-‘為前綴;
    * 多個不需要選項參數的選項,可以合并。(譬如:foo -a -b -c ---->foo -abc)
    * 選項與其參數之間用空白符隔開;
    * 選項參數不可選。
    * 若選項參數有多值,要將其並為一個字串傳進來。譬如:myprog -u "arnold,joe,jane"。這種情況下,需要自己解決這些參數的分離問題。
    * 選項應該在運算元出現之前出現。
    * 特殊參數‘--'指明所有參數都結束了,其後任何參數都認為是運算元。
    * 選項如何排列沒有什麼關係,但對互斥的選項,如果一個選項的操作結果覆蓋其他選項的操作結果時,最後一個選項起作用;如果選項重複,則順序處理。
    * 允許運算元的順序影響程式行為,但需要作文檔說明。
    * 讀寫指定檔案的程式應該將單個參數'-'作為有意義的標準輸入或輸出來對待。

  GNU鼓勵程式員使用--help、--verbose等形式的長選項。這些選項不僅不與POSIX約定衝突,而且容易記憶,另外也提供了在所有GNU工具之間保持一致性的機會。GNU長選項有自己的約定:
    * 對於已經遵循POSIX約定的GNU程式,每個短選項都有一個對應的長選項。
    * 額外針對GNU的長選項不需要對應的短選項,僅僅推薦要有。
    * 長選項可以縮寫成保持惟一性的最短的字串。
    * 選項參數與長選項之間或通過空白字元活通過一個'='來分隔。
    * 選項參數是可選的(只對短選項有效)。
    * 長選項允許以一個虛線為首碼。

  C程式通過argc和argv參數訪問它的命令列參數,通過main()函數調用和處理:int main(int argc, char *argv[])。一般情況下,我們事先約定好參數的順序位置,然後在main函數中進行簡單處理。這種方式實現比較簡單,然後使用者使用起來很不方便,Linux下的各種工具的命令列參數可以是不分先後次序的。幸運的是,Linux為C程式員提供了相關的命令列參數解析函數:getopt()和getopt_long(),分別用於處理短選項和長選項,當然後者可以同時處理短、長選項。函數原型如下:

#include <unistd.h>

int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

          getopt() 函數是一個標準庫調用,可允許使用直接的 while/switch 語句方便地逐個處理命令列參數和檢測選項(帶或不帶附加的參數)。getopt_long() 允許在幾乎不進行額外工作的情況下處理更具描述性的長選項,非常受開發人員的歡迎。下面用筆者開發的一個Daemon程式wsiod中的參數處理來說明具體的處理過程。wsiod參數協助資訊如下:

[liuag] /home/liuag/workspace/WSIO/WSIO-1.3/server > ./wsiod --help
Usage:  wsiod [OPTION]

WSIO server based on web service.
Mandatory arguments to long options are mandatory for short options too.
        -h, --host           hostname in soap_bind, default is host which the service runs
        -p, --port           port which the sercer runs on, default is 8080
        -b, --backlog        request backlog, default is 100
        -t, --type           server type, default is COMMON
        -k, --keepalive      attempt to keep socket connections alive
        -c, --chunk          use HTTP chunking
        -d, --dime           use DIME encoding
        -D, --debug          print debug info
            --help           print this help

Server type:
        COMMON               the simplest server
        STANDALONE           stand-alone server, which can run on port 80
        MULTITHREAD          multi-thread stand-alone server
        POOL                 using a pool of servers
        QUEUE                using a queue of requests for server
        GSI                  prethreaded server with GSI enabled

Report bugs to <Aigui.LIU@ihep.ac.cn>.

wsiod參數處理實現C程式段如下:

#include <unistd.h>
#include <getopt.h>

enum SERVERTYPE{COMMON, STANDALONE, MULTITHREAD, POOL, QUEUE, GSI};
int keepalive = 0, dime = 0, chunk = 0;

/* WSIO server main function */
int main(int argc, char **argv)
{
  int c;
  char host[128] = "localhost";
  char log_buf[LOGBUFSZ];
  int port = 8080, backlog = 100;
  enum SERVERTYPE servertype  = COMMON;
  int helpflg = 0,
      errflg = 0,
      debug = 0;
  struct option longopts[] =
  {
    {"host", 1, 0, 'h'},
    {"port", 1, 0, 'p'},
    {"backlog", 1, 0, 'b'},
    {"type", 1, 0, 't'},
    {"keepalive", 0, 0, 'k'},
    {"chunk", 0, 0, 'c'},
    {"dime", 0, 0, 'd'},
    {"debug", 0, 0, 'D'},
    {"help", 0, &helpflg, 1},
    {0, 0, 0, 0}
  };

  while ((c = getopt_long (argc, argv, "h:p:b:t:kcdD", longopts, NULL)) != EOF)
  {
    switch(c)
    {
      case 'h':
        sprintf(host, "%s", optarg);
        break;
      case 'p':
        port = atoi(optarg);
        break;
      case 'b':
        backlog = atoi(optarg);
        break;
      case 't':
        switch(*optarg)
    {
      case 'C':
        servertype = COMMON;
        break;
      case 'S':
        servertype = STANDALONE;
        break;
      case 'M':
        servertype = MULTITHREAD;
        break;
      case 'P':
        servertype = POOL;
        break;
      case 'Q':
        servertype = QUEUE;
        break;
      case 'G':
        servertype = GSI;
      default:
        break;
    }
        break;
      case 'k':
          keepalive = 1;
    break;
      case 'c':
          chunk = 1;
    break;
      case 'd':
          dime = 1;
    break;
      case 'D':
          debug = 1;
    break;
      case '?':
        errflg++;
        break;
      default:
        break;
    }
  }

  if(helpflg || errflg)
  {
     fprintf(stderr,"Usage:    wsiod [OPTION]/n/n%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
         "WSIO server based on web service./n",
    "Mandatory arguments to long options are mandatory for short options too./n",
    "/t-h, --host           hostname in soap_bind, default is host which the service runs/n ",
    "/t-p, --port           port which the sercer runs on, default is 8080/n",
    "/t-b, --backlog        request backlog, default is 100/n",
    "/t-t, --type           server type, default is COMMON/n",
    "/t-k, --keepalive      attempt to keep socket connections alive/n",
        "/t-c, --chunk          use HTTP chunking/n",
        "/t-d, --dime           use DIME encoding/n",
        "/t-D, --debug          print debug info/n",
    "/t    --help           print this help/n/n",
    "Server type:/n",
    "/tCOMMON               the simplest server/n",
    "/tSTANDALONE           stand-alone server, which can run on port 80/n"
    "/tMULTITHREAD          multi-thread stand-alone server/n",
    "/tPOOL                 using a pool of servers/n",
    "/tQUEUE                using a queue of requests for server/n",
    "/tGSI                  prethreaded server with GSI enabled/n/n",
    "Report bugs to <Aigui.LIU@ihep.ac.cn>./n"
     );
    exit(0);
  }

  /* 省略部分 */

  return 0;
}

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/liuben/archive/2008/04/05/2252929.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.