getopt_long
1 | int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex); |
argc和argv是main方法的入参,argc是长度,argv是地址数组指针
optstring是短选项字符串格式
- 形式 a:bc::, b表示只有一个字符,没有参数;a:表示a后面可以加一个参数;c::表示参数可选,但是如果带参数不能有空格 -c100
- eg:-a 200 b -c100
longopts是长选项结构体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23struct option
{
const char *name;
int has_arg;
int *flag;
int val;
};
eg:
static struct option longOpts[] = {
{ "daemon", no_argument, NULL, 'D' },
{ "dir", required_argument, NULL, 'd' },
{ "out", required_argument, NULL, 'o' },
{ "log", required_argument, NULL, 'l' },
{ "split", required_argument, NULL, 's' },
{ "http-proxy", required_argument, &lopt, 1 },
{ "http-user", required_argument, &lopt, 2 },
{ "http-passwd", required_argument, &lopt, 3 },
{ "http-proxy-user", required_argument, &lopt, 4 },
{ "http-proxy-passwd", required_argument, &lopt, 5 },
{ "http-auth-scheme", required_argument, &lopt, 6 },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }name 是长选项
val是短选项
has_arg 是有没有参数
- no_argument 无参数,
- required_argument 有参数,且格式为 –o 100 或者–out=100
- optional_argument有参数,格式只能为–out=100
flag参数有两个意思
- 如果是NULL,命中长选项时返回短短选项字符串
- 如果不为NULL,命中长选项时返回0,flag=短选项值
longindex longopts数组中匹配到的option位置
全局变量
- optarg:表示当前选项对应的参数值。
- optind:表示的是下一个将被处理到的参数在argv中的下标值。
- opterr:如果opterr = 0,在getopt、getopt_long、getopt_long_only遇到错误将不会输出错误信息到标准输出流。opterr在非0时,向屏幕输出错误。
- optopt:表示没有被未标识的选项。
返回值
- 如果短选项找到,那么将返回短选项对应的字符。
- 如果长选项找到,如果flag为NULL,返回val。如果flag不为空,返回0
- 如果遇到一个选项没有在短字符、长字符里面。或者在长字符里面存在二义性的,返回“?”
- 如果解析完所有字符没有找到(一般是输入命令参数格式错误,eg: 连斜杠都没有加的选项),返回“-1”
- 如果选项需要参数,忘了添加参数。返回值取决于optstring,如果其第一个字符是“:”,则返回“:”,否则返回“?”。
DEMO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135//
// Created by juneleo on 2022/12/29.
//
using namespace std;
void showUsage() {
//cout << "Usage: " << PACKAGE_NAME << " [options] URL ..." << endl;
cout << "Options:" << endl;
cout << " -d, --dir=DIR The directory to store downloaded file." << endl;
cout << " -o, --out=FILE The file name for downloaded file." << endl;
cout << " -l, --log=LOG The file path to store log. If '-' is specified," << endl;
cout << " log is written to stdout." << endl;
cout << " -D, --daemon Run as daemon." << endl;
cout << " -s, --split=N Download a file using s connections. s must be" << endl;
cout << " between 1 and 5. If this option is specified the" << endl;
cout << " first URL is used, and the other URLs are ignored." << endl;
cout << " --http-proxy=HOST:PORT Use HTTP proxy server. This affects to all" << endl;
cout << " URLs." << endl;
cout << " --http-user=USER Set HTTP user. This affects to all URLs." << endl;
cout << " --http-passwd=PASSWD Set HTTP password. This affects to all URLs." << endl;
cout << " --http-proxy-user=USER Set HTTP proxy user. This affects to all URLs" << endl;
cout << " --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects to all URLs." << endl;
cout << " --http-auth-scheme=SCHEME Set HTTP authentication scheme. Currently, BASIC" << endl;
cout << " is the only supported scheme." << endl;
cout << " -v, --version Print the version number and exit." << endl;
cout << " -h, --help Print this message and exit." << endl;
cout << "URL:" << endl;
cout << " You can specify multiple URLs. All URLs must point to the same file" << endl;
cout << " or a download fails." << endl;
cout << "Examples:" << endl;
cout << " Download a file by 1 connection:" << endl;
cout << " aria2c http://AAA.BBB.CCC/file.zip" << endl;
cout << " Download a file by 2 connections:" << endl;
cout << " aria2c -s 2 http://AAA.BBB.CCC/file.zip" << endl;
cout << " Download a file by 2 connections, each connects to a different server." << endl;
cout << " aria2c http://AAA.BBB.CCC/file.zip http://DDD.EEE.FFF/GGG/file.zip" << endl;
cout << "Reports bugs to <tujikawa at rednoah dot com>" << endl;
}
int main(int argc, char* argv[]) {
bool stdoutLog = false;
string logfile;
string dir;
string ufilename;
int split = 0;
bool daemonMode = false;
int c;
while(1) {
int optIndex = 0;
int lopt;
static struct option longOpts[] = {
{ "daemon", no_argument, NULL, 'D' },
{ "dir", required_argument, NULL, 'd' },
{ "out", required_argument, NULL, 'o' },
{ "log", required_argument, NULL, 'l' },
{ "split", required_argument, NULL, 's' },
{ "http-proxy", required_argument, &lopt, 1 },
{ "http-user", required_argument, &lopt, 2 },
{ "http-passwd", required_argument, &lopt, 3 },
{ "http-proxy-user", required_argument, &lopt, 4 },
{ "http-proxy-passwd", required_argument, &lopt, 5 },
{ "http-auth-scheme", required_argument, &lopt, 6 },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "Dd:o:l:s:vh", longOpts, &optIndex);
printf("返回值: %c\n",c);
if(c == -1) {
break;
}
switch(c) {
case 0:{
switch(lopt) {
case 1: {
printf("1: %s\n",optarg);
break;
}
case 2:
printf("2: %s\n",optarg);
break;
case 3:
printf("3: %s\n",optarg);
break;
case 4:
printf("4: %s\n",optarg);
break;
case 5:
printf("5: %s\n",optarg);
break;
case 6:
printf("6: %s\n",optarg);
break;
}
break;
}
case 'D':
printf("D: %s\n",optarg);
break;
case 'd':
printf("d: %s\n",optarg);
break;
case 'o':
printf("o: %s\n",optarg);
break;
case 'l':
printf("l: %s\n",optarg);
break;
case 's':
printf("s: %s\n",optarg);
break;
case 'v':
printf("s: %s\n",optarg);
//showVersion();
exit(0);
case 'h':
showUsage();
exit(0);
default:
showUsage();
exit(1);
}
}
return 0;
}测试
1
2
3
4
5
6
7./getopt_test --out=file.txt --dir=/Users/juneleo/ --http-proxy=192.168.0.0
返回值: o
o: file.txt
返回值: d
d: /Users/juneleo/
返回值:
1: 192.168.0.0