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

来源:互联网 发布:亚加装饰 知乎 编辑:程序博客网 时间:2024/06/05 11:35

方法一

在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
原创粉丝点击