C語言記錄之getopt()

在寫程序的時候,咱們常常須要用到命令行參數,因此今天咱們看看c語言中的getopt()這個函數。數組

咱們先看看下面這個app

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

        ......函數

    }spa


argc寄存了命令行參數個數(注意:包括程序名自己,也包括咱們後面會提到的選項和選項參數)
命令行

咱們在命令行運行 ./ppyy.sh    ok    ko    pp    pe指針

對應的關係是: argv[0]    argv[1]    argv[2]    argv[3]    argv[4]get


可是隻是這麼用,對我來講是不夠的,記不記得咱們在命令行常常使用ps -ef這樣的命令,-ef就是命令行選項,它就像開關同樣。string

爲了能具有命令行選項這樣的功能,咱們今天來看看getopt()這個函數。it


首先,咱們來看看一段程序<注:這段源程序來自head first>

#include <stdio.h>
#include <unistd.h>          //getopt()在unistd.h這個頭文件中提供

int main(int argc,char *argv[]){
    char *delivery = "";
    int thick = 0;
    int count = 0;
    char ch;

    while ((ch = getopt(argc,argv,"d:t")) != EOF ){
        switch (ch){
            case 'd':
                delivery = optarg;
                break;
            case 't':
                thick = 1;
                break;
            default:
                fprintf(stderr,"Unknown option:'%s'\n",optarg);

            return 1;
        }

    }

    argc -= optind;
    argv += optind;

    if (thick)
        puts("Thick crust.");

    if (delivery[0])
        printf("To be delivered %s.\n",delivery);

    puts("Ingredients:");
    for (count=0;count<argc;count++)
        puts(argv[count]);
    
    return 0;
}


接下來,咱們逐一來解讀getopt()在這段程序中如何工做的。

    while ((ch = getopt(argc,argv,"d:t")) != EOF )

    一、首先咱們採用循環來獲取getopt函數的返回值,直到命令行結尾,由於getopt函數沒有選項處理時,是返回-1。

    二、getopt()函數中的"d:t",表明d和t是有效選項,同時d後面是有選項參數的,它寄存在optarg這個變量裏面。

  

        switch (ch){
            case 'd':
                delivery = optarg;
                break;
            case 't':
                thick = 1;
                break;
            default:
                fprintf(stderr,"Unknown option:'%s'\n",optarg);
    一、這一段很簡單明瞭了吧,採用switch處理咱們的命令行參數,是d的時候,就把寄存在變量optarg中的選項參數賦值給delivery。

    二、default,默認當咱們匹配不上有效的命令行參數的時候,咱們就把它輸出到標準錯誤。


    argc -= optind;
    argv += optind;

    上面這兩個,可能不太好理解,由於咱們須要先弄清楚getopt()這個函數的內部工做原理。

    getopt()的函數聲明:int getopt(int argc,char * const argv[ ],const char * optstring);

    getopt是從argv[1]到argv[argc-1]進行逐一處理的,它會把選項和選項參數依次放到argv數組裏邊去,再依次把其餘命令行參數放到argv數組中(選項和選項參數的後面)。

舉個例子,若是開始輸入的命令是

            ./order_pizza -t Anchovies Pineapple -d now

    那麼argv[]數組會依次接收他們的值並進行存放,此時argv[]數組是["./order_pizza", "-t","Anchovies", "Pineapple", "-d", "now"] ,可是getopt函數在處理完成後,argv[]數組裏面的順序是["/order_pizza" , "-t" , "-d" , "now" , "Anchovies" ,"Pineapple"]

     optind這個變量則保存了getopt()函數處理了幾個選項和選項參數,初始化是1(插一句,爲何初始化是1不是0呢,由於咱們須要考慮程序自己,這個在argv中的數組元素),因此若是讀取了3個選項和選項參數,則getopt函數處理完成之後,optind的值是4。

     ok,如今回過頭來看上面的argc -= optind;和argv += optind;   它的意思是,在getopt函數處理完成後,讓咱們跳過已經處理過的命令行選項和選項參數,因此此時的argc=2,而argv須要前進4位(數組地址變更)。

     

        if (thick)
            puts("Thick crust.");

        if (delivery[0])
            printf("To be delivered %s.\n",delivery);

        puts("Ingredients:");
        for (count=0;count<argc;count++)
            puts(argv[count]);

         這上面的代碼就很簡單了,基本不用咱們解釋了。


補充,是關於getopt函數聲明中,對optstring這個參數的處理:

    1) 單個字符,表示選項。
    2) 單個字符後接一個冒號」:」,表示該選項後必須跟一個選項參數。參數緊跟在選項後或者以空格隔開。該參數的指針賦給optarg。
    3) 單個字符後跟兩個冒號」:」,表示該選項後必須跟一個選項參數。參數必須緊跟在選項後不能以空格隔開。該參數的指針賦給optarg。(這個特性是GNU的擴展)。


另外,還有optopt和opterr這些變量,不過上面的已經足夠咱們理解getopt()這個函數的核心了。

相關文章
相關標籤/搜索