"); //-->
在linux中,经常需要各种命令,通常情况下都会带各种参数,而这些参数是如何解析的呢?通常使用GNU C提供的函数getopt、getopt_long、getopt_long_only函数来解析命令行参数。
一、关于命令行参数 命令行参数可以分为两类,一类是短选项,一类是长选项,短选项在参数前加一杠"-",长选项在参数前连续加两杠"--",如下表(ls 命令参数)所示,其中-a,-A,-b都表示短选项,--all,--almost-all, --author都表示长选项。他们两者后面都可选择性添加额外参数。比如--block-size=SIZE,SIZE便是额外的参数。
二、getopt_long函数 getopt函数只能处理短选项,而getopt_long函数两者都可以,可以说getopt_long已经包含了getopt_long的功能。因此,这里就只介绍getopt_long函数。而getopt_long与getopt_long_only的区别很小,等介绍完getopt_long,在提起会更好。
#include <unistd.h> extern char *optarg; extern int optind, opterr, optopt; #include <getopt.h> int getopt(int argc, 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);
参数以及返回值介绍(以上三个函数都适用):1、argc和argv和main函数的两个参数一致。2、optstring: 表示短选项字符串。 形式如“a:b::cd:“,分别表示程序支持的命令行短选项有-a、-b、-c、-d,冒号含义如下: (1)只有一个字符,不带冒号——只表示选项, 如-c (2)一个字符,后接一个冒号——表示选项后面带一个参数,如-a 100 (3)一个字符,后接两个冒号——表示选项后面带一个可选参数,即参数可有可无,如果带参数,则选项与参数直接不能有空格 形式应该如-b2003、longopts:表示长选项结构体。结构如下:
struct option
{
const char *name;
int has_arg;
int *flag;
int val;
};
eg:
static struct option longOpts[] = {
{ "daemon", no_argument, NULL, 'D' },
{ "dir", required_argument, NULL, 'd' },
{ "out", required_argument, NULL, 'o' },
{ "log", required_argument, NULL, 'l' },
{ "split", required_argument, NULL, 's' },
{ "http-proxy", required_argument, &lopt, 1 },
{ "http-user", required_argument, &lopt, 2 },
{ "http-passwd", required_argument, &lopt, 3 },
{ "http-proxy-user", required_argument, &lopt, 4 },
{ "http-proxy-passwd", required_argument, &lopt, 5 },
{ "http-auth-scheme", required_argument, &lopt, 6 },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};(1)name:表示选项的名称,比如daemon,dir,out等。 (2)has_arg:表示选项后面是否携带参数。该参数有三个不同值,如下: a: no_argument(或者是0)时 ——参数后面不跟参数值,eg: --version,--help b: required_argument(或者是1)时 ——参数输入格式为:--参数 值 或者 --参数=值。eg:--dir=/home c: optional_argument(或者是2)时 ——参数输入格式只能为:--参数=值 (3)flag:这个参数有两个意思,空或者非空。 a:如果参数为空NULL,那么当选中某个长选项的时候,getopt_long将返回val值。 eg,可执行程序 --help,getopt_long的返回值为h. b:如果参数不为空,那么当选中某个长选项的时候,getopt_long将返回0,并且将flag指针参数指向val值。 eg: 可执行程序 --http-proxy=127.0.0.1:80 那么getopt_long返回值为0,并且lopt值为1。 (4)val:表示指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值val。
4、longindex:longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值。5、全局变量: (1)optarg:表示当前选项对应的参数值。 (2)optind:表示的是下一个将被处理到的参数在argv中的下标值。 (3)opterr:如果opterr = 0,在getopt、getopt_long、getopt_long_only遇到错误将不会输出错误信息到标准输出流。opterr在非0时,向屏幕输出错误。 (4)optopt:表示没有被未标识的选项。6、返回值: (1)如果短选项找到,那么将返回短选项对应的字符。 (2)如果长选项找到,如果flag为NULL,返回val。如果flag不为空,返回0 (3)如果遇到一个选项没有在短字符、长字符里面。或者在长字符里面存在二义性的,返回“?” (4)如果解析完所有字符没有找到(一般是输入命令参数格式错误,eg: 连斜杠都没有加的选项),返回“-1” (5)如果选项需要参数,忘了添加参数。返回值取决于optstring,如果其第一个字符是“:”,则返回“:”,否则返回“?”。注意: (1)longopts的最后一个元素必须是全0填充,否则会报段错误 (2)短选项中每个选项都是唯一的。而长选项如果简写,也需要保持唯一性。
1、官网给出测试用例。
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <getopt.h>
int
main(int argc, char **argv)
{
int c;
int digit_optind = 0;
while (1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] = {
{"add", required_argument, 0, 0 },
{"append", no_argument, 0, 0 },
{"delete", required_argument, 0, 0 },
{"verbose", no_argument, 0, 0 },
{"create", required_argument, 0, 'c'},
{"file", required_argument, 0, 0 },
{0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "abc:d:012",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
printf("option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break;
case '0':
case '1':
case '2':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf("option %c\n", c);
break;
case 'a':
printf("option a\n");
break;
case 'b':
printf("option b\n");
break;
case 'c':
printf("option c with value '%s'\n", optarg);
break;
case 'd':
printf("option d with value '%s'\n", optarg);
break;
case '?':
break;
default:
printf("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
}
exit(EXIT_SUCCESS);
}2、自己项目相关一个例子。
#include<stdio.h>
#include <getopt.h>
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
void showUsage() {
//cout << "Usage: " << PACKAGE_NAME << " [options] URL ..." << endl;
cout << "Options:" << endl;
cout << " -d, --dir=DIR The directory to store downloaded file." << endl;
cout << " -o, --out=FILE The file name for downloaded file." << endl;
cout << " -l, --log=LOG The file path to store log. If '-' is specified," << endl;
cout << " log is written to stdout." << endl;
cout << " -D, --daemon Run as daemon." << endl;
cout << " -s, --split=N Download a file using s connections. s must be" << endl;
cout << " between 1 and 5. If this option is specified the" << endl;
cout << " first URL is used, and the other URLs are ignored." << endl;
cout << " --http-proxy=HOST:PORT Use HTTP proxy server. This affects to all" << endl;
cout << " URLs." << endl;
cout << " --http-user=USER Set HTTP user. This affects to all URLs." << endl;
cout << " --http-passwd=PASSWD Set HTTP password. This affects to all URLs." << endl;
cout << " --http-proxy-user=USER Set HTTP proxy user. This affects to all URLs" << endl;
cout << " --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects to all URLs." << endl;
cout << " --http-auth-scheme=SCHEME Set HTTP authentication scheme. Currently, BASIC" << endl;
cout << " is the only supported scheme." << endl;
cout << " -v, --version Print the version number and exit." << endl;
cout << " -h, --help Print this message and exit." << endl;
cout << "URL:" << endl;
cout << " You can specify multiple URLs. All URLs must point to the same file" << endl;
cout << " or a download fails." << endl;
cout << "Examples:" << endl;
cout << " Download a file by 1 connection:" << endl;
cout << " aria2c http://AAA.BBB.CCC/file.zip" << endl;
cout << " Download a file by 2 connections:" << endl;
cout << " aria2c -s 2 http://AAA.BBB.CCC/file.zip" << endl;
cout << " Download a file by 2 connections, each connects to a different server." << endl;
cout << " aria2c http://AAA.BBB.CCC/file.zip http://DDD.EEE.FFF/GGG/file.zip" << endl;
cout << "Reports bugs to <tujikawa at rednoah dot com>" << endl;
}
int main(int argc, char* argv[]) {
bool stdoutLog = false;
string logfile;
string dir;
string ufilename;
int split = 0;
bool daemonMode = false;
int c;
while(1) {
int optIndex = 0;
int lopt;
static struct option longOpts[] = {
{ "daemon", no_argument, NULL, 'D' },
{ "dir", required_argument, NULL, 'd' },
{ "out", required_argument, NULL, 'o' },
{ "log", required_argument, NULL, 'l' },
{ "split", required_argument, NULL, 's' },
{ "http-proxy", required_argument, &lopt, 1 },
{ "http-user", required_argument, &lopt, 2 },
{ "http-passwd", required_argument, &lopt, 3 },
{ "http-proxy-user", required_argument, &lopt, 4 },
{ "http-proxy-passwd", required_argument, &lopt, 5 },
{ "http-auth-scheme", required_argument, &lopt, 6 },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "Dd:o:l:s:vh", longOpts, &optIndex);
printf("返回值: %c\n",c);
if(c == -1) {
break;
}
switch(c) {
case 0:{
switch(lopt) {
case 1: {
printf("1: %s\n",optarg);
break;
}
case 2:
printf("2: %s\n",optarg);
break;
case 3:
printf("3: %s\n",optarg);
break;
case 4:
printf("4: %s\n",optarg);
break;
case 5:
printf("5: %s\n",optarg);
break;
case 6:
printf("6: %s\n",optarg);
break;
}
break;
}
case 'D':
printf("D: %s\n",optarg);
break;
case 'd':
printf("d: %s\n",optarg);
break;
case 'o':
printf("o: %s\n",optarg);
break;
case 'l':
printf("l: %s\n",optarg);
break;
case 's':
printf("s: %s\n",optarg);
break;
case 'v':
printf("s: %s\n",optarg);
//showVersion();
exit(0);
case 'h':
showUsage();
exit(0);
default:
showUsage();
exit(1);
}
}
return 0;
}四、参考文章[1].https://blog.csdn.net/cashey1991/article/details/7942809
[2].https://www.jianshu.com/p/7a0a8d882787
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
Gartner发布2025中国网络安全技术成熟度曲线
简易无线电子琴电路
美军混合电驱动车辆发展近况
25键多功能电子琴电路
智能产线亮相CIOE中国光博会 破解AI时代光模块生产痛点
感测技术的未来:具备高 dV/dt 抗扰度和 5kV 隔离的 XtremeSense™ TMR 电流传感器
西安光机所携“硬实力”亮相中国光博会
德州仪器推出业界灵敏度领先的面内霍尔效应开关
基于DDS的快速跳频频率合成器的设计
爱史牌S903型天线放大器
美海军舰艇发展重大计划展望
基于C语言的TMS320C32 DSP的中断编程方法及BOOT功能实现
简易电子琴电路
请大家推荐一本关于protel dxp的教材
无法解释的误会
美海军开发潜射无人机
基于DDS技术的声纳信号模拟器
指画
ST紧凑灵活的功率开关提高汽车安全性能
给大家推荐一个好的电子网站,不看会后悔的
芯科科技FG23L无线SoC现已全面供货
美海军潜艇技术发展新动向
小型电子琴电路
美军APKWS II制导火箭弹技术发展动态
苹果“前方超燃” 新品亮相!IDC全面深度分析
IDC预计,2029年中国大数据总体市场规模将超730亿美元
基于CAN总线和DSP的起重机多功能安全监控系统
非隔离式开关电源PCB布局设计技巧
基于DDS技术的智能超声波功率源的研制
有关s3c4510b uclinux开机过程。。。。