红联Linux门户
Linux帮助

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

发布时间:2016-08-16 10:04:02来源:linux网站作者:qianshanxue11
方法一
在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),声明程序可以使用的选项,假如说后面跟着: ,说明这个选项需要输入参数。
如果后面跟着:: ,那说明这个参数是可选(也可以不选)。
以下面的程序为例:
选项:
-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测试例程也有使用这个函数的。
相对于手册例程更容易理解,那作为第一个示例程序
#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”,那么就简单的可以看到这个选项的含义。
能够使用长字符串作为选项,是这个函数与之前函数的区别。
 
本文永久更新地址://m.ajphoenix.com/linux/23353.html