第一次接觸這個函數,是因爲學習mjpg-streamer的源碼。
函數作用:對命令行選項進行解析。
函數出處
頭文件getopt.h中:
#include <getopt.h>
int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
參數介紹
optstring:短選項字符串
longopts: struct option數組,用於存放長選項參數
longindex:用於返回長選項在longopts結構體數組的索引值,用於調試;一般置爲NULL
先介紹一下struct option
struct option {
const char *name; //長選項名
int has_arg; //是否需要參數
int *flag;
int val;
};
參數has_arg的值:
# define no_argument 0 //if the option does not take an argument
# define required_argument 1 //if the option requires an argument
# define optional_argument 2 //if the option takes an optional argument
參數flag和val相互依賴,主要分兩種情況:
(1)flag爲NULL,val值用於確定該長選項,所以需要爲長選項指定唯一的val值。這裏也爲長選項和短選項建立了橋樑。
(2)flag不爲NULL,則將val值存放到flag所指向的存儲空間,用於標識該長選項出現過。
返回值
(1)短選項: 程序中使用短選項,則返回短選項字符(如‘n’),當需要參數時,則在返回之前將參數存入到optarg中。
(2)0/val值: 程序中使用長選項,返回值根據flag和val值確定。
①當flag爲NULL時,返回val值(所以根據val值做不同處理,即val必須唯一)。當val值等於短選項值,則可以使用短選項解析函數解析長選項。
②當flag不爲NULL時,則將val值存入flag所指向的存儲空間,getopt_long_only()返回0
(3)?: 出現未定義的長選項,函數返回“?”
(4)-1: 解析完所有參數之後返回-1(即當函數解析完參數返回-1之後跳出while循環)
實例
實例1:文件getopt.c源碼:
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h> //getopt_long()頭文件位置
int main(int argc, char** argv)
{
const char *optstring = "n:v";
int c, deb, index;
struct option opts[] = {
{"username", required_argument, NULL, 'n'},
{"version", no_argument, NULL, 'v'},
{"debug", no_argument, &deb, 1},
{0,0,0,0}
};
while( (c = getopt_long_only(argc, argv, optstring, opts, &index)) != -1)
{
switch(c)
{
case 'n': //使用-n 或者 --username 指定用戶名
printf("username is %s\n",optarg);
break;
case 'v': //使用-v 或者--version,輸出版本號
printf("version is 0.0.1 \n");
break;
case 0: //flag不爲NULL
printf("debug is %d\n",deb);
break;
case '?': //選項未定義
printf("?\n");
break;
default:
printf("c is %d\n",c);
break;
}
}
return 0;
}
編譯運行結果分析:
$ ./getopt -n won
username is won
$ ./getopt -v
version is 0.0.1
$ ./getopt -w
./getopt: unrecognized option '-w'
?
$ ./getopt -d
debug is 1
實例2:文件getopt_1.c源碼:(有點問題)
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
int main(int argc, char** argv)
{
const char *optstring="n:v";
int c,deb,index;
struct option opts[]={
{"username",required_argument,0,0},
{"n",required_argument,0,0},
{"version",no_argument,0,0},
{"v",no_argument,0,0},
{"debug",no_argument,0,0},
{"d",no_argument,0,0},
{"help",no_argument,0,0},
{"h",no_argument,0,0}
};
while((c=getopt_long_only(argc,argv,optstring,opts,&index))!=-1)
{
switch(index){
//-n或者--username
case 0:
case 1:
printf("username:%s\n",optarg);
break;
//-v或者--version
case 2:
case 3:
printf("version:1.0.0\n");
break;
//-d or --debug
case 4:
case 5:
printf("debug:yes\n");
break;
//-h or --help
case 6:
case 7:
printf("Help:?\n");
break;
default:
printf("other:%d\n",index);
break;
}
}
return 0;
}
執行結果分析:
$ ./getopt_1 --username won --version -d -h
username:won
version:1.0.0
debug:yes
Help:?
$ ./getopt_1 -j
Segmentation fault