getopt和getopt_long

liuyuan185442111發表於2018-10-03

getopt

#include <getopt.h> // man裡說是#include <unistd.h>
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

如果選項成功找到,返回選項字元;如果所有命令列選項都解析完畢,返回 -1;如果遇到選項字元不在 optstring 中,返回字元 ‘?’,並將 optopt 置為該選項字元;如果遇到丟失引數,返回 ‘?’ 或 ‘:’,當返回返回 ‘?’ 時且 opterr 非 0 會提示錯誤資訊。

optarg —— 指向當前選項引數(如果有)的指標或NULL(無引數)。
optind —— 再次呼叫 getopt() 時下一個 argv-element 的索引。
optopt —— 最後一個未知選項。
opterr ­—— 是否希望 getopt() 向 stderr 列印出錯資訊,0 為不列印,opterr 預設非0。

optstring:由三部分組成,第一部分是可選的字元’+‘或’-’,第二部分是一個可選的字元’;’,第三部分是具體的選項字串。
舉例說明第三部分 “ab:c::d:e”,abcde 分別是選項字元,選項字元其後跟 “:” 表示該選項有引數,選項跟引數之間可有空格,也可沒有空格,選項字元後跟 “::” 表示引數可有可無,但如果有引數選項和引數之間不能有空格,選項字元後不跟 “:” 或 “::” 表示該選項沒引數。"-ae -b100 -c -d 200"就是一個對應於上述 optstring 的命令選項,沒引數的選項可以寫在一起,比如 -ae。
getopt() 預設情況下會改變引數的順序,從而使 nonoption argv-element 移至所有選項之後,但如果 optstring 第一部分是字元 ‘+’,或者設定了環境變數POSIXLY_CORRECT,第一個 nonoption argv-element 出現時立即停止選項處理,例如 “+ab:c::d:e”,"-ae 100 -c -d 200" 中 100 及其以後的引數都不再作為選項處理。
如果第一部分是 ‘-’,每個 nonoption argv-element 作為選項 1 的引數,這裡的 1 是數字 1 不是字元 1。
如果第二部分的 ‘:’ 存在,當丟失選項引數時 getopt() 不再返回 ‘?’ 而是返回 ‘:’,且不會列印出錯資訊。

The special argument “–” forces an end of option-scanning regardless of the scanning mode.

#include <stdio.h>
#include <getopt.h>
int main(int argc, char *argv[])
{
        int opt;
        const char *optstring = "ab:c::d:e";
        while (((opt = getopt(argc, argv, optstring))) != -1)
        {
                printf("opt = %c(%d)\t", opt, opt);
                printf("optarg = %s\t", optarg);
                printf("optind = %d\t", optind);
                printf("argv[optind] = %s\t", argv[optind]);
                printf("optopt = %c\(%d)n", optopt, optopt);
        }
        printf("after processing optind = %d, argv[optind] = %s\n", optind, argv[optind]);
}

./a.out file -ae -b100 -c -z -d 200
opt = a(97)     optarg = (null) optind = 2      argv[optind] = -ae      optopt = (0)
opt = e(101)    optarg = (null) optind = 3      argv[optind] = -b100    optopt = (0)
opt = b(98)     optarg = 100    optind = 4      argv[optind] = -c       optopt = (0)
opt = c(99)     optarg = (null) optind = 5      argv[optind] = -z       optopt = (0)
./a.out: invalid option -- 'z'
opt = ?(63)     optarg = (null) optind = 6      argv[optind] = -d       optopt = z(122)
opt = d(100)    optarg = 200    optind = 8      argv[optind] = (null)   optopt = z(122)
after processing optind = 7, argv[optind] = file

./a.out file  -ae -- -b100 -c -z -d 200
opt = a(97)     optarg = (null) optind = 2      argv[optind] = -ae      optopt = (0)
opt = e(101)    optarg = (null) optind = 3      argv[optind] = --       optopt = (0)
after processing optind = 3, argv[optind] = file

getopt_long

#include <getopt.h>
struct option {
    const char *name;
    int         has_arg;
    int        *flag;
    int         val;
};
int getopt_long(int argc, char * const argv[], const char *optstring,
           const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char * const argv[], const char *optstring,
           const struct option *longopts, int *longindex);

The getopt_long() function works like getopt() except that it also accepts long options, started with two dashes. A long option may take a parameter, of the form --arg=param or --arg param.

option 的成員意義如下:
name
長選項的名字。
has_arg
no_argument (or 0) 選項沒有引數;required_argument (or 1) 選項有一個引數ment; optional_argument (or 2) 選項可有可無引數。
flag
標識結果如何返回。選項如果被找到,如果 flag 是 NULL,getopt_long() 將會返回 val,否則 getopt_long() 返回 0,而且 *flag 被設定為 val;選項如果未被找到,getopt_long() 返回 ‘?’,*flag(如果 flag 不為 NULL ) 保持不變。
val
標識返回值。

longopts 的最後一個元素必須 be filled with zeros。
如果 longindex 不是 NULL,*longindex 將被設定為長選項在 longopts 中的索引。

getopt_long_only() is like getopt_long(), but ‘-’ as well as “–” can indicate a long option. If an option that starts with ‘-’ (not “–”) doesn’t match a long option, but does match a short option, it is parsed as a short option instead.

參考

https://linux.die.net/man/3/getopt

相關文章