Linux getopt函數處理傳入參數

一、Linux傳入參數處理shell

在介紹使用getopt函數處理應用程序傳入參數前,先來看一下Linux環境下編寫的應用程序是如何處理傳入的參數的數組

Linux環境編寫應用程序時,main函數通常會有兩個參數,用於描述執行應用程序時傳入的參數,書寫形式以下:函數

int main(int argc, char *argv[])
  • argc:表示傳入參數的個數
  • argv:指針數組,每一項存放一個傳入參數字符串的地址

在shell中啓動這個應用程序,shell接受用戶輸入命令行,將命令行分解成單詞,而後把這些單詞放入到一個數組,操做系統將這個存放單詞數組的長度和數組做爲參數傳遞給了main函數。所以,實際狀況下,argv[0]指向的必定是運行當前應用程序的全路徑名稱,argv[1]~argv[argc-1]指向的纔是傳入參數,實際傳入參數的個數爲argc-1spa

例若有一個名爲hello_world應用程序,在shell中按照 "./hello_world 3" 執行該程序,此時,argc = 2,argv[0]指向的是 "./hello_world" 字符串存放地址,argv[1]指向的纔是傳入參數 "3" 字符串存放地址
操作系統

顯然,咱們能夠在main函數內本身編寫程序,經過解析argc,argv參數來獲取執行應用程序所傳入的參數。但對於Linux這種普遍使用的操做系統,它已經在庫函數中爲用戶提供了用於命令行參數解析的函數,咱們直接調用這些函數,即可輕鬆的解析各類命令行參數模式命令行

這裏所講的getopt函數,就是標準庫中實現的一個用於解析命令行參數的函數,它支持須要關聯值和不須要關聯值的選項,並且簡單易用指針

(所謂的須要關聯值的選項,以gcc編譯器爲例子,gcc的-o選項表示輸出可執行程序名稱,這個後面就須要跟一個名稱才能正常使用,後面一個參數就是-o命令的關聯值;所謂的不須要關聯值,以ls命令爲例子, ls的-l命令表示列出當前目錄全部文件,這個後面不須要跟一些其餘信息,這種被稱做不須要關聯值的選項)code

二、getopt函數的原型blog

getopt函數有三個參數,函數的原型以下:索引

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

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

getopt函數本質上其實就是對main函數傳入的argc和argv參數進行處理,它將傳遞給程序的main函數的argc和argv做爲參數,同時接受一個選項指定字符串optstring。optstring字符串告訴getopt哪些選項可用,以及它們是否有關聯值。

optstring是一個字符串列表,每一個字符表明一個單字符選項。若是一個字符後面緊跟一個冒號(:),則表示一個該選項有一個關聯值做爲下一個參數。

例如:getopt(argc, argv, "if:l")

它容許-i、-f、-l做爲參數,其中-f選項後要緊跟一個參數,也就是它的關聯值。這裏參數的傳遞能夠不按照optstring字符串列表寫入的順序來傳

getopt的返回值是argv數組中的下一個選項字符,循環調用getopt能夠依次獲得argv中每個選項。函數的處理行爲以下:

  • 若是選項處理完畢,返回值爲-1。循環遇到-1,參數判斷完畢,能夠退出循環
  • 若是選項有一個關聯值,全局變量optarg指向這個值
  • 若是遇到不在optstring中選項,getopt返回一個問號(?),並將沒法識別選項存放到全局變量optopt,有些getopt版本會在遇到未知選項時打印錯誤信息
  • 若是選項要求有關聯值,可是用戶沒傳入一個關聯值,默認狀況下getopt一般返回一個問號(?)。咱們能夠將選項字符串的第一個字符設置成冒號,這個沒傳入關聯值時,返回的是冒號(:)而不是問號(?)

optind表示下一個待處理參數的索引,getopt利用它來記錄本身的進度,通常狀況下在程序中不多用到

三、函數的使用

編寫一個簡單的例子,來演示getopt函數使用

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


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

    while((res = getopt(argc, argv, ":io:l")) != -1)
    {
        switch(res)
        {
            case 'i':
            case 'l':
                    printf("option: %c\n", res);
                    break;
                    
            case 'o':
                    printf("option: %c %s\n", res, optarg);
                    break;
                    
            case ':':
                    printf("option need a value\n");
                    break;
                    
            case '?':
                    printf("unknown option: %c\n", optopt);
                    break;
                    
            default:
                    break;
        }
    }
}

演示程序中的main函數內使用getopt函數對傳入參數進行解析,支持參數有-i、-o、-l,其中-o參數後要有一個關聯值。這裏optstring參數的第一個字符設置成冒號,是用來分辨輸入-o選項,但沒傳入關聯值狀況,這種狀況(:)被返回

若是傳入-i、-l參數,打印參數信息

若是傳入-o參數,打印參數信息和關聯值信息

若是傳入-o參數,並沒傳入關聯值,打印出提示信息

若是傳入無效參數時,打印出不識別提示信息

四、小結

調用getopt函數能夠方便的處理咱們程序中傳入的不一樣參數,它按照咱們指定的方式來解析main函數中傳入的argc和argv參數,並返回選項字符。支持的參數在getopt的optstring參數指定,經過參數後面冒號(:)的有無來表示該參數後面是否須要緊跟關聯值信息。但getopt函數也有本身的侷限性,它僅支持的是單字符參數,若是想接受比單字符選項含義更明確的參數時,就不適用了。不過,若是你有這種需求,能夠去研究下C庫中getopt函數的另外一個加強版本——getopt_long,它接受如下劃線(--)開始的長參數

相關文章
相關標籤/搜索