linux 下如何处理命令行参数 getopt函数

方法一

在Linux这类操作系统中,有大量的命令行处理程序,之前测试SPI的时候./mxc_spi_test1.out -D 0 -s 1000000 -b 8 E6E0

参数非常多,这么多的命令行参数它是怎么去分析的呢?

首先第一种方法是 freescale提供的例程里一种方法。

	for(i = 1; i < argc; i++) {
		if(!strcmp(argv[i], "-D")) {
			i++;
			spi_id = atoi(argv[i]);
			if (spi_id < 0 || spi_id > 2) {
				printf("invalid parameter for device option\n");
				help_info(argv[0]);
				return -1;
			}
		} else if(!strcmp(argv[i], "-s")) {
			i++;
			speed = atoi(argv[i]);
		} else if(!strcmp(argv[i], "-b")) {
			i++;
			bits_per_word = atoi(argv[i]);
		} else if(!strcmp(argv[i], "-H"))
			mode |= SPI_CPHA;
		else if(!strcmp(argv[i], "-O"))
			mode |= SPI_CPOL;
		else if(!strcmp(argv[i], "-C"))
			mode |= SPI_CS_HIGH;
		else if((i != (argc - 1))) {
			printf("invalid parameter\n");
			help_info(argv[0]);
			return -1;
		}
	}

argc存储的是输入的参数的个数,argv指针存储并根据输入顺序找到各个参数。

第零个参数是执行的 程序名。

下面小程序可以测试

#include <stdio.h>
int main(int argc, char ** argv)
{
 int i;
 for (i=0; i < argc; i++)
  printf("Argument %d is %s.\n", i, argv[i]);
 return 0;
}

按照下列方式执行

hello.exe a b c d e

结果可以看出

Argument 0 is hello.exe.
Argument 1 is a.
Argument 2 is b.
Argument 3 is c.
Argument 4 is d.
Argument 5 is e.

方法二getopt


下面第二种方法,是linux 下的getopt函数。

int getopt (int argc, char *const *argv, const char *options)

argc ,argv直接从main传递过来。

GNU C说明手册上

The options argument is a string that specifies the option characters that are valid
for this program. An option character in this string can be followed by a colon (‘:’)

to indicate that it takes a required argument. If an option character is followed by
two colons (‘::’), its argument is optional

意思是options 选项是一个string(这个字符串里面的每一个字母,是被当作单独选项的。所以无法为一个选项取名--na,会被解析为两个选项-n -a),声明程序可以使用的选项,假如说后面跟着: ,说明这个选项需要输入参数。

如果后面跟着:: ,那说明这个参数是可选(也可以不选)。

以下面的程序为例:参照http://blog.csdn.net/mr_jj_lian/article/details/6835137
选项:
  • -n —— 显示“我的名字”。
  • -g —— 显示“我女朋友的名字”。
  • -l —— 带参数的选项.
#include <stdio.h>

#include <getopt.h>


int main(int argc, char **argv)
{
    int cc;
    opterr=0;
    char *b_opt_arg;

    while((cc=getopt(argc,argv,"ngl:")) !=-1)
    {
	switch(cc)
	     {        
	case 'n':
            printf("My name is xiaoming.\n");
            break;
        case 'g':
            printf("Her name is xiaohong.\n");
            break;
        case 'l':
            b_opt_arg = optarg;
            printf("Our love is %s\n", optarg);
            break;
		}

    }

return 0;
}

执行结果

gao64@ubuntu:~/cproject/getoptprojects$ ./outnames    //没有参数,但是并没有报警提示,因为前面声明了opterr=0
gao64@ubuntu:~/cproject/getoptprojects$ ./outnames -n  //选项n
My name is xiaoming.
gao64@ubuntu:~/cproject/getoptprojects$ ./outnames -g    选项g
Her name is xiaohong.
gao64@ubuntu:~/cproject/getoptprojects$ ./outnames -l forever   选项l,带参数forever,并把参数作为字符串输出
Our love is forever
gao64@ubuntu:~/cproject/getoptprojects$


The GNU C Library Reference Manual上有这样一个例程

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>  //include <getopt.h>

int main(int argc, char *argv[])
{
    int aflag=0;
    int bflag=0;
    char *cvalue=NULL;
    int index;
    int c;
    opterr=0;
    while ((c=getopt(argc,argv,"abc:"))!=-1)
        switch (c) {
        case 'a':
            aflag=1;
            break;
        case 'b':
            bflag=1;
            break;
        case 'c':
            cvalue=optarg;
            break;
        case '?':
        if(optopt=='c')
            fprintf(stderr,"Option -%c requires an argument.\n",optopt);
        else if (isprint(optopt))
            fprintf(stderr,"Unknown option '-%c'.\n",optopt);
        else
        fprintf(stderr,"Unknown option character '\\x%x'.\n",optopt);
        return 1;
        default:
            abort();

        }
    printf("aflag=%d,bflag=%d,cvalue=%s\n",aflag,bflag,cvalue);

    for(index=optind;index<argc;index++)
        printf("Non-option argument %s\n",argv[index]);
    return 0;

}


测试结果如下,多种形式测试

gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt         //无参数输入
aflag=0,bflag=0,cvalue=(null)
gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt -a -b    //正常输入a,b 选项
aflag=1,bflag=1,cvalue=(null)
gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt -ab     //正常输入a,b选项,但是ab之间无短符号-
aflag=1,bflag=1,cvalue=(null)
gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt -c         //输入c选项,但是c无参数输入,报警提示
Option -c requires an argument
aflag=0,bflag=0,cvalue=test
gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt -ctest    //输入c选项,正常输入c参数
aflag=0,bflag=0,cvalue=test
gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt arg1     //错误输入参数,
aflag=0,bflag=0,cvalue=(null)
Non-option argument arg1
gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt -a arg1   //错误输入参数,因为a选项没有参数输入
aflag=1,bflag=0,cvalue=(null)
Non-option argument arg1
gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt -c test arg1  
aflag=0,bflag=0,cvalue=test
Non-option argument arg1
gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt -a -- -b   
aflag=1,bflag=0,cvalue=(null)
Non-option argument -b
gao64@ubuntu:~/cproject/getopt/libcgetopt/build-libcgetopt-Desktop_Qt_5_6_0_GCC_64bit-Debug$ ./libcgetopt -a -
aflag=1,bflag=0,cvalue=(null)
Non-option argument -

方法三 getopt_long

GNU C 手册上还提到这个函数。

在SPI测试例程也有使用这个函数的。比如http://blog.csdn.net/stephen_yu/article/details/7205671

关于这个函数的使用,这个例程来自网站http://www.jb51.net/article/41462.htm

相对于手册例程更容易理解,那作为第一个示例程序

#include <stdio.h> 
#include <getopt.h> 
char *l_opt_arg; 
char* const short_options = "nbl:"; 
struct option long_options[] = { 
{ "name", 0, NULL, 'n' }, 
{ "bf_name", 0, NULL, 'b' }, 
{ "love", 1, NULL, 'l' }, 
{ 0, 0, 0, 0}, 
}; 
int main(int argc, char *argv[]) 
{ 
int c; 
while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) 
{ 
switch (c) 
{ 
case 'n': 
printf("My name is XL./n"); 
break; 
case 'b': 
printf("His name is ST./n"); 
break; 
case 'l': 
l_opt_arg = optarg; 
printf("Our love is %s!/n", l_opt_arg); 
break; 
} 
} 
return 0; 
} 
[root@localhost wyp]# gcc -o getopt getopt.c 
[root@localhost wyp]# ./getopt -n -b -l forever 
My name is XL. 
His name is ST. 
Our love is forever! 
[root@localhost liuxltest]# 
[root@localhost liuxltest]# ./getopt -nb -l forever 
My name is XL. 
His name is ST. 
Our love is forever! 
[root@localhost liuxltest]# ./getopt -nbl forever 
My name is XL. 
His name is ST. 
Our love is forever!

到这里会有疑问,那么这个函数与上面函数不是一样么?

有什么区别呢?

gao64@ubuntu:~/cproject/getoptprojects$ ./getoptlong1 --name --bf_name --love loveforeverlong
My name is XL.
His name is ST.
Our love is loveforeverlong!

由此可见,选项可以支持字符串,比如之前的选项是-n ,不太容易懂选项的意思,现在可以直接使用 “-- name”,那么就简单的可以看到这个选项的含义。

能够使用长字符串作为选项,是这个函数与之前函数的区别。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值