方法一
在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