getopt使用方法
使用場景
在Linux中,輸入命令"ls -al",可以顯示指定工作目錄下的內容。
-a 顯示所有文件及目錄 (. 開頭的隱藏文件也會列出)
-l 除文件名稱外,亦將文件型態、權限、擁有者、文件大小等資訊詳細列出
"-al"是選項,那這個選項是怎么被識別的呢?就和getopt這個函數相關。
getopt可以用來解析命令的選項,以及選項的參數。"ls -al /home"中"-al"是選項,"/home"是參數。
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;?
參數
argc? —— 提供給主函數的參數個數
argv —— 參數的字符串數組的指針
optstring —— 由三部分組成,第一部分是可選的字符’+‘或’-’,第二部分是一個可選的字符’:’,第三部分是具體的選項字符串。
1. 單個字符:表示選項后不帶參數。
2. 單個字符后接一個冒號:表示該選項后必須跟一個參數。參數緊跟在選項后或者以空格隔開。該參數的指針賦給optarg。
3.?單個字符后跟兩個冒號:表示該選項后可以跟一個參數,也可以不跟。如果跟一個參數,參數必須緊跟在選項后不能以空格隔開。該參數的指針賦給optarg。如果沒有跟參數,則optarg = NULL。
舉例說明
第三部分 “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() 不再返回 ‘?’ 而是返回 ‘:’,且不會打印出錯信息。
?
返回值
如果選項成功找到,返回選項字符;
如果所有命令行選項都解析完畢,返回 -1;
如果遇到選項字符不在 optstring 中,返回字符 ‘?’,并將 optopt 置為該選項字符;
如果遇到丟失參數,返回 ‘?’ 或 ‘:’,當返回返回 ‘?’ 時且 opterr 非 0 會提示錯誤信息。
?
optarg —— 指向當前選項參數(如果有)的指針或NULL(無參數)。
optind —— 再次調用 getopt() 時下一個 argv-element 的索引。
optopt —— 最后一個未知選項。
opterr -—— 是否希望 getopt() 向 stderr 打印出錯信息,0 為不打印,opterr 默認非0。
?
案例
#include <stdio.h> #include <unistd.h>int main(int argc, char *argv[]) {int ch;char *seg1, *seg2, *seg3;//如果 'n' 沒有冒號 ':', 則 optarg 為 (null)//如果 'n' 有冒號 ':', 則 optarg 為 第一個選項//下面有運行結果while((ch = getopt(argc,argv,"n:"))!= -1){switch(ch){case 'n': //n為name開頭字母seg1=optarg;seg2=argv[optind];seg3=argv[optind+1];printf("option's seg1: +%s\n",seg1);printf("option's seg2: +%s\n",seg2);printf("option's seg3: +%s\n",seg3);break;default:printf("unrecongnized option :%c\n",ch);break;}}return 0; }輸入命令
./optget_test -n Jack Mike Bob運行結果('n'有冒號':')
option's seg1: +Jack option's seg2: +Mike option's seg3: +Bob運行結果('n'沒有冒號':')
option's seg1: +(null) option's seg2: +Jack option's seg3: +Mike?
?
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);option 的struct成員意義如下:
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:標識返回值。
?
?
?
getopt_long_only
#include <getopt.h> struct option {const char *name;int has_arg;int *flag;int val; }; int getopt_long_only(int argc, char * const argv[], const char *optstring,const struct option *longopts, int *longindex);option 的struct成員意義如下:
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:標識返回值。
?
?
?
案例
#include <stdio.h> /* for printf */ #include <stdlib.h> /* for exit */ #include <getopt.h> /* for getopt_long_only */static struct option long_options[] = {{"add", required_argument, 0, 'a' },{"sub", required_argument, 0, 's' },{"mul", required_argument, 0, 'm' },{"div", required_argument, 0, 'd' },{"help",no_argument, 0, 'h' },{0, 0, 0, 0 }, };int main(int argc, char **argv) {char ch;int val[2];int res;int option_index = 0;while((ch = getopt_long_only(argc, argv, "a:s:m:d:h",long_options, &option_index)) != -1){switch(ch){case 'a':sscanf(optarg, "%d", &val[0]);sscanf(argv[optind], "%d", &val[1]);res = val[0] + val[1];printf("%d + %d = %d\n", val[0], val[1], res);break;case 's':sscanf(optarg, "%d", &val[0]);sscanf(argv[optind], "%d", &val[1]);res = val[0] - val[1];printf("%d - %d = %d\n", val[0], val[1], res);break;case 'm':sscanf(optarg, "%d", &val[0]);sscanf(argv[optind], "%d", &val[1]);res = val[0] * val[1];printf("%d * %d = %d\n", val[0], val[1], res);break;case 'd':sscanf(optarg, "%d", &val[0]);sscanf(argv[optind], "%d", &val[1]);res = val[0] / val[1];printf("%d / %d = %d\n", val[0], val[1], res);break;case 'h':printf("commend list:\n");printf("-add [value1] [value2]: add\n");printf("-sub [value1] [value2]: subtract\n");printf("-mul [value1] [value2]: multiply\n");printf("-div [value1] [value2]: divide\n");printf("-help\n");break;default:break;}}exit(EXIT_SUCCESS); }?
getopt_long和getopt_long_only區別
getopt_long 支持的?--add 1 2 \ -a 1 2
getopt_long_only 支持的 -add 1 2 \ --add 1 2 \ -a 1 2 \ --a?1 2
?
?
總結
以上是生活随笔為你收集整理的getopt使用方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 圆形面积与周长(仅用于个人记录)
- 下一篇: unity不规则碰撞_Unity中的刚体