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中的选项。

选项和参数的概念:

  1. 单个字符,表示选项;(例如 g++ -o main main.cpp -std=c++11,其中o就是命令行的选项,而后面的main就是选项所带的参数。)
  2. 单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。
  3. 单个字符后跟两个冒号,表示该选项后必须跟一个参数。参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给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:

#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;
}

int main(int argc, char *argv[])
{
	testFun1(argc,argv);
	//testFun2(argc,argv);
    return 0;
}

执行结果:

[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,解析输入的"abcde":

#include <iostream>
#include <unistd.h>
#include <string>

using namespace std;

//解析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;
}

执行结果:

[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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值