getopt 函式分析

2021-06-27 19:50:49 字數 4252 閱讀 3604

我們知道,linux中在命令列下呼叫程式時,所使用的命令由三部分組成。比如:

gcc -o -o hello hello.c

其中(1)gcc是

命令的名字,

(2)-o是

可選字元, -o也是可選字元,

(3)hello 和 hello.c就是命令列

引數。getopt()函式就是用來解析命令列引數和可選字元的。所以getopt()函式應該是每乙個命令列下執行的程式必須要使用的函式。基本上在這些程式的main函式中,呼叫的第乙個函式就是getopt(),呼叫形式一般如下:

while

((c = getopt(argc, argv,

"xy:z::"))

!=-1)}..

....

. getopt函式的原型如下:

#include

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

extern char *optarg;

extern int optind, opterr, optopt;

getopt()函式用於解析命令列引數。它的引數argc、argv就是main函式的引數,argc表示傳給main函式的引數的個數(每乙個引數都是字串),argv則是乙個char的指標陣列,每乙個指標陣列的元素指向乙個字串引數。

在指標陣列指向的字串引數,

如果以'-'開頭,就表示這個字串引數是乙個「可選部分」。

'-'後面的那個字元就是乙個「可選字元」。如果不斷的呼叫getopt()函式,那麼

它每次從「可選部分」返回乙個「可選字元」。

變數optind是getopt要處理的argv中的下乙個字串引數的索引。

optind被系統初始化為1. 我們可以將它重新賦值為1,從而可以重新開始掃瞄指標陣列argv。

每當getopt()函式找到乙個「可選字元」,它就更新外部變數optind和乙個內部靜態變數nextchar,所以對getopt()函式的下一次呼叫可以從靜態變數nextchar儲存的位置開始。

當分析完了所有的「可選字元」時,getopt()函式返回-1. 同時

optind的值正是陣列argv中第乙個非「可選部分」的索引,也就是說optind是第乙個引數的索引。

getopt()函式的第三個引數optstring是乙個有所有合法的「可選字元」所組成的字串。

《1》在引數optstring的「可選字元」如果後面帶有乙個':',

則表示在該「可選字元」的後面必須有乙個引數。比如「o:"表示: gcc -o arg 在-o的後面必須帶有乙個引數arg. 在getopt()函式解析完"o:"對應的命令列引數時,

char型的指標optarg則指向了引數"arg"。

《2》如果在「可選字元」的後面帶有了兩個':'時,則表示在該「可選字元」後面可能有也可能沒有引數,有引數,則optarg指向引數,沒有則為0。這是gnu的乙個關於getopt()函式的擴充套件。

《3》如果optstring中含有乙個大寫的'w'字元,後面帶有乙個冒號,也就是形如"w:",則表示該「可選字元」是乙個「長選項」,也就是說不是只有乙個字元的「可選字元」。比如:gcc -wall  hello.c 要解析該命令列,getopt()函式中的第三個引數

optstring應該是:"w:all",而且當解析到「-wall"時optarg = "all".  這一點也是gnu對getopt()函式的擴充套件。

《4》如果getopt()函式在argv中解析到乙個沒有包含在optstring中的「可選字元」,它會列印乙個錯誤資訊,並將該「可選字元」儲存在optopt中,

並返回字元'?'。當然,

我們可以將變數opterr賦值為0,來阻止getopt()函式輸出錯誤資訊。

《5》當getopt()函式的第三個引數optstring的第乙個字元是':'時,很顯然,這是由於少寫了乙個"可選字元"的緣故。此時,getopt()函式不返回'?',

而是返回':'來暗示我們漏掉了乙個」可選字元」.

例子1: /

** the following trivial example program uses getopt(

)to handle two

* program options:

-n, with no associated value;

*and

-t val, which expects an associated value.*/

#include 

#include 

#include 

int main(

int argc, char *argv)

}printf(

"flags=%d; tfnd=%d; nsecs=%d; optind=%d\n"

, flags, tfnd, nsecs, optind);if

(optind >

= argc)

printf(

"name argument = %s\n"

, argv[optind]);

/* other code omitted *

/exit

(exit_success);}

編譯:gcc -wall -o getopt getopt.c

執行:./getopt -n -t 120 nessecory_arg

結果:flags=1; tfnd=1; nsecs=120; optind=4

name argument = nessecory_arg

注意:當我們將執行命令改為:./getopt -n -t 120

輸出的結果為:

flags=1; tfnd=1; nsecs=120; optind=4

expected argument after options

這是因為,當getopt()函式解析完了引數時,optind應該是argv指標陣列中第乙個非可選引數的索引。現在沒有「非可選引數」,所以條件「

optind >= argc」成立了,所以輸出了「expected argument after options

例子2:

#include 

#include 

#include 

#include 

int main(

int argc, char *argv)

}exit

(0);}

編譯:gcc -wall -o getopt2 getopt2.c

執行:./getopt2 -i -u username -z filename

結果:current option index:(optind-1)=1, argv[optind-1]=argv[1]=-i

next option index:(optind)=2, argv[optind]=argv[2]=-u

optarg=(null), opterr=1, optopt=0

current option index:(optind-2)=2, argv[optind-2]=argv[2]=-u

next option index:(optind)=4, argv[optind]=argv[4]=-z

optarg=username, opterr=1, optopt=0

current option index:(optind-1)=5, argv[optind-1]=argv[5]=filename

next option index:(optind)=6, argv[optind]=argv[6]=(null)

optarg=filename, opterr=1, optopt=0

例子3:

#include 

#include 

#include 

#include 

int main(

int argc, char *argv)

}exit

(0);}

編譯:gcc -wall -o mygcc gcc.c

執行:./mygcc -wall -o -o mygcc

結果:option char: w

optarg: all

option char: o

optimization flag is open.

option char: o

the obj is: mygcc

這個例子演示了如何利用getopt()函式來解析形如:

gcc -wall -o -o hello hello.c 這樣的引數。

getopt函式分析

函式getopt主要用於拆分命令列引數,用這個函式就不自己寫命令列引數解析程式了,以下 摘自tcpdump原始碼,對這個函式比較感興趣,故對此進行分析注釋,因水平實在不敢恭維,不足之處希望能一起 函式getopt 有三個引數,nargc,nargv就是命令列傳過來的argc和argv字串ostr,它...

getopt 函式分析

getopt 分析命令列引數 相關函式表頭檔案 include 定義函式 int getopt int argc,char const argv const char optstring 函式說明 getopt 用來分析命令列引數。引數argc和argv是由main 傳遞的引數個數和內容。引數opt...

getopt 函式 分析命令列引數

標頭檔案 include 定義函式 int getopt int argc,char const argv,const char optstring 函式說明 getopt 用來分析命令列引數。1 引數argc 和argv 是由main 傳遞的引數個數和內容。2 引數optstring 則代表欲處理...