一、linux应用程序如何接收参数? 1、argc、argv linux应用程序执行时,我们往往通过命令行带入参数给程序,比如:
ls /dev/ -l 其中参数 /dev/ 、**-l**都是作为参数传递给命令 ls
应用程序又是如何接收这些参数的?
通常应用程序都是从main函数开始执行,传统的main函数风格如下:
int main(int argc, char* argv[]) argc:程序的命令行参数的数量,用于统计参数数量。 argv:是一个指向一个字符串数组的指针,数组包含了参数,每个字符串就是一个参数,最后一个元素为0。过一般习惯使用多级指针来操作字符串。 *char argv[]有时候我们也写成char argv,
**argv[]**是一个存放字符类型元素地址的数组。
因为 c 中是有字符串的概念的:将每个字符存放在 char 数组,最后一个元素为****表示字符串的结束。
**printf(%s)**就是输出字符串。
并且一般使用argv指针来访问、处理argv[]数组的内容。
c语言中,数组就是一个指针加偏移量。
所以argv则是指向一个指针数组argv[]的指针,不用定义,直接可以用。
在argv[]数组中存放的的指针指向输入命令的各部分(调用程序、选项、参数)。
2、举例 下面我们用一个实例来理解argc和argv
/** argc: 命令行参数的个数* argv: 字符指针数组(指向各个命令行参数的字符指针所构成的数组)*/int main(int argc, char* argv[]) // 接收命令行参数{ printf(argc=%d,argc); for (int i = 0; i 0 && (*++argv)[0] == '-' { while (c = *++argv[0] { switch(c){ case 'x': ... break; case 'n': ... break; default: printf(xxx: illegal opyion %c, c); ... break; } }} 3、getopt、getopt_long 事实这么处理选项参数是比较麻烦的,
linux提供了选项解析的函数:
// 头文件#include#include /*所在头文件 */int getopt(intargc, char * const argv[], const char *optstring);int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int*longindex);int getopt_long_only(int argc, char * const argv[],const char *optstring, const struct option *longopts, int*longindex);extern char *optarg; /*系统声明的全局变量 */extern int optind, opterr, optopt; 三、getopt 1、定义 int getopt(int argc, char * const argv[], const char *optstring);功能: getopt是用来解析命令行选项参数的,但是只能解析短选项: **-d 100**,不能解析长选项:**--prefix**参数 argc: main()函数传递过来的参数的个数 argv: main()函数传递过来的参数的字符串指针数组 optstring: 选项字符串,告知 getopt()可以处理哪个选项以及哪个选项需要参数返回: 如果选项成功找到,返回选项字母;如果所有命令行选项都解析完毕,返回 -1; 如果遇到选项字符不在 optstring 中,返回字符 ‘?’; 如果遇到丢失参数,那么返回值依赖于 optstring 中第一个字符, 如果第一个字符是 ‘:’ 则返回’:‘,否则返回’?'并提示出错误信息。 2、optstring 含义 【重要】 下边重点举例说明optstring的格式意义:
char*optstring = “ab:”;单个字符a 表示选项a没有参数 格式:-a即可,不加参数单字符加冒号b: 表示选项b有且必须加参数 格式:-b 100或-b100,但-b=100错单字符加2冒号c:: 表示选项c可以有,也可以无 格式:-c200,其它格式错误 上面这个 optstring 在传入之后,getopt 函数将依次检查命令行是否指定了 -a, -b, -c(这需要多次调用 getopt 函数,直到其返回-1),当检查到上面某一个参数被指定时,函数会返回被指定的参数名称(即该字母)
系统声明的4个全局变量含义如下:
optarg —— 指向当前选项参数(如果有)的指针。optind —— 再次调用 getopt() 时的下一个 argv指针的索引。optopt —— 最后一个未知选项。opterr —— 如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。 3、实例 说千道万,不如来一个实例:
#include#include#includeint main(intargc, char *argv[]){ int opt; char *string = a:c:d; while ((opt = getopt(argc, argv, string))!= -1) { printf(opt = %c , opt); printf(optarg = %s ,optarg); printf(optind = %d ,optind); printf(argv[optind] = %s,argv[optind]); } } 正确输入参数,执行结果如下:
peng@ubuntu:~/work/test$ ./peng -a100 -b 200 -c 300 -dopt = a optarg = 100 optind = 2 argv[optind] = -bopt = b optarg = 200 optind = 4 argv[optind] = -copt = c optarg = 300 optind = 6 argv[optind] = -dopt = d optarg = (null) optind = 7 argv[optind] = (null) 或者
ork/test$ ./peng -a100 -b200 -c300 -d opt = a optarg = 100 optind = 2 argv[optind] = -b200opt = b optarg = 200 optind = 3 argv[optind] = -c300opt = c optarg = 300 optind = 4 argv[optind] = -dopt = d optarg = (null) optind = 5 argv[optind] = (null) 输入选项参数错误的情况
peng@ubuntu:~/work/test$ ./peng -a 100 -b 200 -c 300 -dopt = a optarg = (null) optind = 2 argv[optind] = 100opt = b optarg = 200 optind = 5 argv[optind] = -copt = c optarg = 300 optind = 7 argv[optind] = -dopt = d optarg = (null) optind = 8 argv[optind] = (null) 导致解析错误,第一个 optarg = null,实际输入参数 100,由于格式不正确造成的(可选参数格式固定)
参数丢失,也会导致错误 peng@ubuntu:~/work/test$ ./peng -a -b 200 -c opt = a optarg = (null) optind = 2 argv[optind] = -bopt = b optarg = 200 optind = 4 argv[optind] = -c./peng: option requires an argument -- 'c'opt = ? optarg = (null) optind = 5 argv[optind] = (null) c选项是必须有参数的
命令行选项未定义,-e选项未在optstring中定义,会报错: peng@ubuntu:~/work/test$ ./peng -t./peng: invalid option -- 't'opt = ? optarg = (null) optind = 2 argv[optind] = (null) 四、getopt_long 1、定义 int getopt_long(int argc, char * const argv[], const char *optstring,const struct option *longopts,int *longindex);功能: 包含 getopt 功能,增加了解析长选项的功能如:--prefix --help参数: longopts 指明了长参数的名称和属性 longindex 如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是 longopts 的下标值返回: 对于短选项,返回值同 getopt 函数; 对于长选项, 如果 flag 是 null ,返回 val ,否则返回 0 ; 对于错误情况返回值同 getopt 函数 2、struct option struct option { const char *name; /* 参数名称 */ int has_arg; /* 指明是否带有参数 */ int *flag; /* flag=null时,返回value;不为空时,*flag=val,返回0 */ int val; /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */}; 参数has_arg 说明:has_arg 指明是否带参数值,其数值可选:
no_argument 表明长选项不带参数,如:–name, --help required_argument 表明长选项必须带参数,如:–prefix /root或 --prefix=/root optional_argument 表明长选项的参数是可选的,如:–help或 –prefix=/root,其它都是错误 3、实例 #include#include#includeint main(intargc, char *argv[]){ int opt; int digit_optind = 0; int option_index = 0; char *string = a:c:d; static struct option long_options[] = { {reqarg, required_argument,null, 'r'}, {optarg, optional_argument,null, 'o'}, {noarg, no_argument, null,'n'}, {null, 0, null, 0}, }; while((opt =getopt_long_only(argc,argv,string,long_options,&option_index))!= -1) { printf(opt = %c , opt); printf(optarg = %s ,optarg); printf(optind = %d ,optind); printf(argv[optind] =%s , argv[optind]); printf(option_index = %d,option_index); } } 正确执行命令
peng@ubuntu:~/work/test$ ./long --reqarg 100 --optarg=200 --noargopt = r optarg = 100 optind = 3 argv[optind] =--optarg=200 option_index = 0opt = o optarg = 200 optind = 4 argv[optind] =--noarg option_index = 1opt = n optarg = (null) optind = 5 argv[optind] =(null) option_index = 2 或者
peng@ubuntu:~/work/test$ ./long –reqarg=100 --optarg=200 --noargopt = o optarg = 200 optind = 3 argv[optind] =--noarg option_index = 1opt = n optarg = (null) optind = 4 argv[optind] =(null) option_index = 2 可选选项可以不给参数
peng@ubuntu:~/work/test$ ./long --reqarg 100 --optarg --noargopt = r optarg = 100 optind = 3 argv[optind] =--optarg option_index = 0opt = o optarg = (null) optind = 4 argv[optind] =--noarg option_index = 1opt = n optarg = (null) optind = 5 argv[optind] =(null) option_index = 2 输入长选项错误的情况
peng@ubuntu:~/work/test$ ./long --reqarg 100 --optarg 200 --noargopt = r optarg = 100 optind = 3 argv[optind] =--optarg option_index = 0opt = o optarg = (null) optind = 4 argv[optind] =200 option_index = 1opt = n optarg = (null) optind = 6 argv[optind] =(null) option_index = 2 五、getopt_long_only getopt_long_only 函数与 getopt_long 函数使用相同的参数表,在功能上基本一致
只是 getopt_long 只将 --name 当作长参数,但 getopt_long_only 会将 --name 和 -name 两种选项都当作长参数来匹配
getopt_long_only 如果选项 -name 不能在 longopts 中匹配,但能匹配一个短选项,它就会解析为短选项。
六、综合实例 下面这个例子,是从开源项目ifplug提取出来的命令提取小例子, 大家可以根据自己需要,基于这个框架,定制自己的程序。
#define _gnu_source#include #include #include #include #include #include #include #define ethcheckd_version 1.1int delay_up = 0;char *interface = eth0;void usage(char *p) { if (strrchr(p, '/')) p = strchr(p, '/')+1; printf(%s [options] -i --iface=iface specify ethernet interface (%s) -d --delay-up=secs specify delay time (%i) -h --help show this help, p, interface, delay_up);}void parse_args(int argc, char *argv[]) { static struct option long_options[] = { {iface, required_argument, 0, 'i'}, {delay-up, required_argument, 0, 'd'}, {help, no_argument, 0, 'h'}, {version, no_argument, 0, 'v'}, {0, 0, 0, 0} }; int option_index = 0; int help = 0, _kill = 0, _check = 0, _version = 0, _suspend = 0, _resume = 0, _info = 0; for (;;) { int c; if ((c = getopt_long(argc, argv, ihv, long_options, &option_index)) < 0) break; switch (c) { case 'i' : interface = strdup(optarg); printf(interface %s,interface); break; case 'd': delay_up = atoi(optarg); printf(delay_up %d,delay_up); break; case 'h': usage(argv[0]); break; case 'v': printf(peng ethcheckd_version); break; default: fprintf(stderr, unknown parameter.); exit(1); } } }static volatile int alarmed = 0;int main(int argc, char* argv[]) { parse_args(argc, argv); return 0;} 下面是测试结果
短选项 peng@ubuntu:~/work/test$ ./param -hparam [options] -i --iface=iface specify ethernet interface (eth0) -d --delay-up=secs specify delay time (0) -h --help show this helppeng@ubuntu:~/work/test$ ./param -vpeng 1.1peng@ubuntu:~/work/test$ ./param -vhpeng 1.1param [options] -i --iface=iface specify ethernet interface (eth0) -d --delay-up=secs specify delay time (0) -h --help show this help peng@ubuntu:~/work/test$ ./param -i eth3 -d 15interface eth3delay_up 15 peng@ubuntu:~/work/test$ ./param -i eth3 -d 15 -hinterface eth3delay_up 15param [options] -i --iface=iface specify ethernet interface (eth3) -d --delay-up=secs specify delay time (15) -h --help show this help 长选项
peng@ubuntu:~/work/test$ ./param --helpparam [options] -i --iface=iface specify ethernet interface (eth0) -d --delay-up=secs specify delay time (0) -h --help show this help peng@ubuntu:~/work/test$ ./param --versionpeng 1.1peng@ubuntu:~/work/test$ ./param --iface eth3 --delay-up 15interface eth3delay_up 15 talk is cheap!test this code! 快操练起来吧!!!
CAN总线在汽车ECU中的作用
电感电容、谐振器和振荡器的Q值
罗德与施瓦茨和华为共同完成4.5G移动通信下行传输速率测试
安捷伦N9030A频谱分析仪维修按键不灵,不稳定最新案例
Unity云原生分布式运行优化方案
Linux程序之可变参数&&选项那些事
如何解决iphone不能拍照故障
迪文2023全国巡回研讨会武汉、长沙站成功举办
选购高低温冲击试验箱时需要注意什么
pcb走线的规则设置方法介绍
苹果卖不动了?真相是iPhone打破了历史销售记录!
深刻解读动力电池梯级利用技术规范
具二维亚铁磁性石墨烯系统首次合成
数字化医院解决方案
stm32最高工作频率是多少
2019年全球拼接屏增速26% 京东方发力拼接超大尺寸等商显市场
扎根电池产业链用户端采购商,这个展会你值得拥有!
创新力连续四载,再添荣耀!ZLG致远电子荣获24届中国专利奖优秀奖
全球汽车保有量逐年增长, 未来汽车维修服务发展潜力巨大
触摸屏通过RJ45口无线连接200SMART PLC