C/C++—— 分析命令列引數的getopt()函式使用介紹

readyao發表於2016-03-31

函式介紹:

首先輸入命令:man 3 getopt 檢視getopt函式的man手冊介紹

#include <unistd.h>

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

extern char *optarg;
extern int optind, opterr, optopt; 

函式說明 getopt()用來分析命令列引數。引數argc和argv分別代表引數個數和內容,跟main()函式的命令列引數是一樣的。

下面用一個例子來輸出main函式中的argc,argv[ ]內容:

#include <stdio.h>


int main(int argc, char* argv[])
{
    int i = 0;
    printf("共%d個命令列引數\n", argc);
    for(i = 0; i < argc; ++i){
        printf("第%d個引數是: %s\n", i+1, argv[i]);
    }

    return 0;
}
輸出:

root@linux_ever:~/linux_ever/work_test# ./getopt
共1個命令列引數
第1個引數是: ./getopt
root@linux_ever:~/linux_ever/work_test# ./getopt -a -h help
共4個命令列引數
第1個引數是: ./getopt
第2個引數是: -a
第3個引數是: -h
第4個引數是: help

引數 optstring為選項字串, 告知 getopt()可以處理哪個選項以及哪個選項需要引數,
如果選項字串裡的字母后接著冒號“:”,則表示還有相關的引數,全域變數optarg 即會指向此額外引數。
如果在處理期間遇到了不符合optstring指定的其他選項getopt()將顯示一個錯誤訊息,並將全域變數optarg設為“?”字元,如果不希望getopt()列印出錯資訊,則只要將全域變數opterr設為0即可。

getopt() 所設定的全域性變數包括:
optarg---指向當前選項的引數的指標(選項字母:後的引數)。
optind——再次呼叫 getopt() 時的下一個 argv 指標的索引。 optopt——最後一個未知選項。

返回值:

If  an  option  was  successfully  found, then getopt() returns the option character.  If all command-line options have been parsed, then getopt() returns -1.  If getopt() encounters an option character that was not in optstring, then '?' is returned.  If getopt() encounters an option with  a missing  argument,  then  the  return  value  depends  on  the  first character in optstring: if it is ':', then ':' is returned; otherwise '?' is returned.

大概意思就是:

如果一個選項成功被找到,則getopt返回該選項字元,比如a, b, c....
如果所有的選項都被找到,則getopt返回-1。
如果getopt函式遇到了一個在optstring引數中沒有指定的選項,則返回'?'。
如果在-a之後忘了輸出引數,則返回':'(此時optstring中有字元a:),如果不是a:,則返回'?'


optstring中的指定的內容的意義(例如getopt(argc, argv, "ab:c:de::");)
1.單個字元,表示選項,(如上例中的abcde各為一個選項)
2.單個字元後接一個冒號:表示該選項後必須跟一個引數。引數緊跟在選項後或者以空格隔開。該引數的指標賦給optarg。(如上例中的b:c:)
3 單個字元後跟兩個冒號,表示該選項後可以跟一個引數,也可以不跟。如果跟一個引數,引數必須緊跟在選項後不能以空格隔開。
該引數的指標賦給optarg。(如上例中的e::,如果沒有跟引數,則optarg = NULL),但是在例項中測試卻是::沒什麼作用。。


例項:

/*************************************************************************
	> File Name: getopt.c
	> Author: 
	> Mail: 
	> Created Time: 2016年03月31日 星期四 17時18分23秒
 ************************************************************************/

#include <stdio.h>
#include <unistd.h>


int main(int argc, char* argv[])
{
    printf("*****************************************\n");
    int i = 0;
    printf("共%d個命令列引數\n", argc);
    for(i = 0; i < argc; ++i){
        printf("第%d個引數是: %s\n", i+1, argv[i]);
    }
    printf("*****************************************\n");

    char ch;

    while((ch = getopt(argc, argv, "a:bc::h")) != -1){
        //printf("optind = %d, optopt = %d\n", optind, optopt);

        switch(ch){
            case 'a':
                printf("選項是%c, 選項內容: %s\n", ch, optarg);
                break;
            case 'b':
                printf("選項是%c, 選項內容: %s\n", ch, optarg);
                break;
            case 'c':
                printf("選項是%c, 選項內容: %s\n", ch, optarg);
                break;
            case 'h':
                printf("選項是%c\n", ch);
                printf("-a optstring\n");
                printf("-b\n");
                printf("-c optstring or NULL\n");
                printf("-h");
                break;
            default:
                printf("other option: %c\n", ch);
                break;
        }
    }
    return 0;
}

輸出:

root@linux_ever:~/linux_ever/work_test# ./getopt -h
*****************************************
共2個命令列引數
第1個引數是: ./getopt
第2個引數是: -h
*****************************************
選項是h
-a optstring
-b
-c optstring or NULL
-hroot@linux_ever:~/linux_ever/work_test# ./getopt -a linux_ever
*****************************************
共3個命令列引數
第1個引數是: ./getopt
第2個引數是: -a
第3個引數是: linux_ever
*****************************************
選項是a, 選項內容: linux_ever
root@linux_ever:~/linux_ever/work_test# ./getopt -a linux_ever -b
*****************************************
共4個命令列引數
第1個引數是: ./getopt
第2個引數是: -a
第3個引數是: linux_ever
第4個引數是: -b
*****************************************
選項是a, 選項內容: linux_ever
選項是b, 選項內容: (null)
root@linux_ever:~/linux_ever/work_test# ./getopt -a linux_ever -b -c ever         
*****************************************
共6個命令列引數
第1個引數是: ./getopt
第2個引數是: -a
第3個引數是: linux_ever
第4個引數是: -b
第5個引數是: -c
第6個引數是: ever
*****************************************
選項是a, 選項內容: linux_ever
選項是b, 選項內容: (null)
選項是c, 選項內容: (null)


相關文章