C++函数 - getopt函数分析以及命令行解析
在Linux下运行可执行程序时,一般需要带特定参数以指定运行的方式。通过是采用getopt()函数解析传入的参数内容,其头文件为<unistd.h>。
下面来具体介绍getopt的原型:
int getopt(int argc,char * const argv[ ],const char * optstring);
参数argc和argv分别代表参数个数和内容,参数 optstring为选项字符串。
getopt() 所设置的全局变量包括:
- extern char *optarg;
- extern int optind, opterr, optopt;
- optarg——指向当前选项参数(如果有)的指针。
- optind——再次调用 getopt() 时的下一个 argv 指针的索引。
- opterr——是否将错误信息输出到stderr,为0时表示不输出。
- optopt——不在选项字符串optstring中的选项。
选项和参数的概念:
- 单个字符,表示选项;(例如 g++ -o main main.cpp -std=c++11,其中o就是命令行的选项,而后面的main就是选项所带的参数。)
- 单个字符后接一个冒号: 表示该选项后必须跟一个参数。
参数紧跟在选项后或者以空格隔开
。该参数的指针赋给optarg。 - 单个字符后跟两个冒号,表示该选项后必须跟一个参数。
参数必须紧跟在选项后不能以空格隔开
。该参数的指针赋给optarg。
短参数的定义:
getopt()使用optstring所指的字串作为短参数列表,像"1ac:d::"就是一个短参数列表。短参数的定义是一个'-'后面跟一个字母或数字,例如-a, -b就是一个短参数。每个数字或字母定义一个参数。
其中短参数在getopt定义里分为三种:
1. 不带值的参数,它的定义即是参数本身。 2. 必须带值的参数,它的定义是在参数本身后面再加一个冒号。 3. 可选值的参数,它的定义是在参数本身后面加两个冒号 。
以"1ac:d::"为例,其中的1,a就是不带值的参数,c是必须带值的参数,d是可选值的参数。 在实际调用中,'-1 -a -c cvalue -d', '-1 -a -c cvalue -ddvalue', '-1a -ddvalue -c cvalue'都是合法的。注意事项:
1. 不带值的参数可以连写,像1和a是不带值的参数,它们可以-1 -a分开写,也可以-1a或-a1连写。 2. 参数不分先后顺序,'-1a -c cvalue -ddvalue'和'-d -c cvalue -a1'的解析结果是一样的。 3. 要注意可选值的参数的值与参数之间不能有空格,必须写成-ddvalue这样的格式,如果写成-d dvalue这样的格式就会解析错误。
测试程序1,解析输入的ip,port和msg:
- 类的this可以通过对象或者指针来绑定
测试程序1:
DETAILS
#include <iostream>
#include <unistd.h>
#include <string>
using namespace std;
//解析ip, port, msg.
void testFun1(int argc, char *argv[])
{
std::string ip = "127.0.0.1";
int port = 8080;
std::string msg = "Hello World";
int opt;
const char *str = "i:p:m:";
while ((opt = getopt(argc, argv, str)) != -1)
{
switch (opt)
{
case 'i':
{
ip = optarg;
break;
}
case 'p':
{
port = atoi(optarg);
break;
}
case 'm':
{
msg = optarg;
break;
}
default:
break;
}
}
cout<<"ip: "<<ip<<endl;
cout<<"port: "<<port<<endl;
cout<<"msg: "<<msg<<endl;
}
//解析2ab:c:de::
void testFun2(int argc, char *argv[])
{
int opt;
const char *str = "2ab:c:de::";
while ((opt = getopt(argc, argv, str)) != -1)
{
switch (opt)
{
case '2':
cout<<"HAVE option: -2"<<endl;
break;
case 'a':
cout<<"HAVE option: -a"<<endl;
break;
case 'b':
cout<<"HAVE option: -b"<<endl;
cout<<"The value of -b is "<<optarg<<endl;
break;
case 'c':
cout<<"HAVE option: -c"<<endl;
cout<<"The value of -c is "<<optarg<<endl;
break;
case 'd':
cout<<"HAVE option: -d"<<endl;
break;
case 'e':
cout<<"HAVE option: -e"<<endl;
cout<<"The value of -e is "<<optarg<<endl;
break;
default:
break;
}
}
}
int main(int argc, char *argv[])
{
//testFun1(argc,argv);
testFun2(argc,argv);
return 0;
}
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
执行结果: bash
[root@192 main函数命令行解析]# ./main
ip: 127.0.0.1
port: 8080
msg: Hello World
[root@192 main函数命令行解析]# ./main -i 10.43.33.115 -p 8888 -m Test
ip: 10.43.33.115
port: 8888
msg: Test
2
3
4
5
6
7
8
测试程序2,解析输入的"abcde":
执行结果:
[root@192 main函数命令行解析]# ./main -a -b 123 -c 456 -d -e 555
HAVE option: -a
HAVE option: -b
The value of -b is 123
HAVE option: -c
The value of -c is 456
HAVE option: -d
HAVE option: -e
The value of -e is [root@192 main函数命令行解析]# ./main -b 123 -c 456 -d -e555 -a2
HAVE option: -b
The value of -b is 123
HAVE option: -c
The value of -c is 456
HAVE option: -d
HAVE option: -e
The value of -e is 555
HAVE option: -a
HAVE option: -2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18