Linux下getopt函數使用Tips

來源:互聯網
上載者:User
getopt函數可以用來非常方便的處理命令列參數。函數的原型是:

int getopt(int argc, char * const argv[], const char *optstring);

以下是關鍵點:
1. argc, argv就是main函數的那兩個。optstring是我們給出的格式字串,特別的是格式字串中的:表示該command option後面是有一個value的,比如:./xtop -n 20 -i 2 1111,在這裡optstring就可以寫成"n:i:",這表示n和i這兩個是command option,而且這兩個option後面都需要給value,如果沒有:,就表示該option後面不需要value。有關optstring還有一些 約定,比如以+開頭就有特殊含義,具體看man 3 getopt了。
2. 傳回值。正常情況下,返回的是一個char,表示當前分析到的option字母,這樣,下面就可以用一個switch來處理了。全部分析完畢後,返回 -1。如果碰到一個沒有出現在optstring中的option,那麼,getopt返回?(預設情況下)。其實不用這麼麻煩,一般coding的時 候,將我們需要處理的option字母全部列出來以後,然後用一個default就可以將其他任何getopt的傳回值視為非法,列印:Usage: xxxx這樣的字串,程式退出即可。
3. 注意點:出現在optstring中的我們指定的那些option不是強制的。比如說,上面例子中,我們要求-n, -i這兩個option都是必須要設定的,而使用者在執行程式的時候只給出了一個-n,那麼,getopt是管不了這個事的。他只是呆板的從頭往後分析以- 打頭的token,然後給我們返回option字母。所以,對於這種情況,我們要自己在程式中檢測使用者是否對我們強制要求的option都設定了,否則, 就報錯。事實上,按照option和argument的原理來說,option應該都是可選的,不然怎麼叫optiton呢?應該把強制要求使用者佈建的全 部變成argument,這樣是最符合邏輯的。
4. 前面說了,對於-n 20這樣的option,getopt返回的是n這個字母,然後這個20怎麼取到呢?getopt將option的value放在了一個全域變數中,名字 為optarg,類型是char *。我們通過訪問optarg就可以取到這個value了。如果使用者寫的option是-n2,那麼,getopt返回n,同時optarg的值是 -n2,這裡也是需要我們手工判斷的。除非使用者寫的是-n,後面沒了,此時按照optstring中的要求,getopt會列印出錯資訊,同時返回?。
5. 最後,關於argument。也就是getopt分析完了所有的option之後,最後剩下的就是argument了。在上面的例子中,./xtop -n 20 -i 2 1111,這個最後的1111就是argument了。getopt會設定全域變數optind(類型是int),這個optind就是第一個 argument(也就是不以-打頭的token,同時也不是option value的token)在argv數組中的index,也就是說,argv[optind]就可以取出這個argument。非常方便吧。這樣,由於有 了這個optind,所以,事實上,使用者在寫命令列的時候就可以很自由了,可以將option混著寫,也可以將argument和option混著寫,不 用一定要把argument放在命令列的最後。

基本上注意點就是這些,附上xtop中的相關代碼。getopt還有一些特殊的說明和feature,在man 3 getopt中都可以找到。此外,還有getopt_long這樣的函數,可以用來handle --打頭的長option,這個在man手冊中也有說明。

    int main(int argc, char *argv[])
    {
       int opt;

       // argument handling
        while ((opt = getopt(argc, argv, "n:i:o:")) != -1) {
            switch(opt) {
            case 'n':
                if (!string_is_int(optarg)) {
                    fprintf(stderr, "Error: <times> should be an integer. Yours is %s\n", optarg);
                    goto FAILED;
                }
                check_times = atoi(optarg);
                break;
            case 'i':
                if (!string_is_int(optarg)) {
                    fprintf(stderr, "Error: <time interval> should be an integer. Yours is %s\n", optarg);
                    goto FAILED;
                }
                check_interval = atoi(optarg);
                break;
            case 'o':
                output_file = (char *)malloc(strlen(optarg) + 1);
                if (output_file == NULL) {
                    fprintf(stderr, "Error: malloc for output file failed.\n");
                    goto FAILED;
                }
                strcpy(output_file, optarg);
                break;
            default:
                printf("Usage: xtop -n <times> -i <time interval> [-o <output file>] <pid>\n");
                goto FAILED;
            }
        }

       // check whether the -n & -i are set
        if (check_times <= 0 || check_interval <= 0) {
            fprintf(stderr, "Usage: xtop -n <times> -i <time interval> [-o <output file>] <pid>\n");
            fprintf(stderr, "Also make sure your <times>, <time interval> are positive integers.\n");
            goto FAILED;
        }

        if (optind >= argc) {
            fprintf(stderr, "Error: <pid> argument can't be found.\n");
            goto FAILED;
        }
        if (!string_is_int(argv[optind])) {
            fprintf(stderr, "Error: <pid> should be an integer. Yours is %s\n", argv[optind]);
            goto FAILED;
        }
        pid = atoi(argv[optind]);
        if (pid <= 0) {
            fprintf(stderr, "Error: illegal <pid> argument. Pid should be a positive integer. Yours is %d\n", pid);
            goto FAILED;
        }

       // -o <output file> is optional, so check whether the user set this
       // xtop.out is the default output filename
        if (output_file == NULL) {
            printf("Begin analysing process %d, checking %d times after every %d seconds. Record results into xtop.out\n",
                   pid, check_times, check_interval);
        } else {
            printf("Begin analysing process %d, checking %d times after every %d seconds. Record results into %s\n",
                   pid, check_times, check_interval, output_file);
        }

       ............
    }

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.