1.argc和argv
int main()
{
}
有时候main()函数不写argc,argv参数,程序默认也有,只不过我们用不了。
为什么是argc,argv?
这只是一种规范,形式参数名字也可以是a,b之类的。
ls -al /home
在Linux下,我们给程序传入参数,bash会使用通配符扩展字符串,然后填入字符串数组argv。
不过在MS-DOS下,命令行的输入并不会被解析,而是直接传递给程序,由程序自己解析。
短横线"-“一般被称为"开关"或"标志”。
argc:一共有多少个参数。
argv:字符串数组(二维数组),存储命令行参数(包括程序名)。
#include <stdio.h>
int main(int argc, char **argv)
{
int arg;
printf("参数个数:%d\n",argc);
for(arg=1; arg < argc; arg++)
{
if(argv[arg][0] == '-')
printf("开关/选项:%s\n", argv[arg]+1);
else
printf("参数:%s\n", argv[arg]);
}
return 0;
}
运行:
root@ubuntu:/home/chenjianzhen/CPP# ./opt -l /home -at file "hello world"
参数个数:6
开关/选项:l
参数:/home
开关/选项:at
参数:file
参数:hello world
2.getopt
man 3 getopt,查看详细信息
不支持特殊参数“–”:比如ls --help.
#include <unistd.h>
/*函数功能:用于解析命令行参数
*参 数:将main函数的argc,argv作为输入参数;
* optstring:选项指定符字符串,告诉getopt哪些选项可用,以及它们是否有关联值。
* 每个字符代表一个单字符选项,如果一个字符后跟着一个冒号(:),表明该
* 选项有一个关联值作为下一个参数。
*返 回 值:argv数组里下一个选项字符。循环调用getopt就可以依次得到每个选项。
* 1、如果选项有关联值,那么外部变量optarg会指向这个值;
* 2、如果选项处理完毕,返回-1,遇到特殊参数"--"会停止扫描;
* 3、如果遇到无法识别的选项,返回一个问号(?),并保存到外部变量optopt中;
* 4、如果一个选项要求有关联值,用户却没有提供,getopt会返回一个问号(?)。
* 如果把选项字符串的第一个字符设置为':',则getopt会在用户未提供值得情况下返回':'。
**/
int getopt(int argc, char * const argv[],const char *optstring);
extern char *optarg;// optarg保留选项的关联值
extern int optind, opterr, optopt;
//外部变量optind被设置为下一个非选项参数的索引;getopt使用它来记录自己的进度。当所有选项参数处理完成后,optind指向argv数组其余参数的位置。
//如果opterr是非0值,getopt会向stderr打印一条出错信息。
//optopt用于保存无法识别的选项。
代码示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int opt;
//循环处理所有选项,选项处理完毕则返回-1
while((opt = getopt(argc, argv, "if:al")) != -1)
{
//可用选项为'i','f','a','l',其中'f'选项有关联值
switch(opt)
{
case 'i':
case 'a':
case 'l':
printf("参数:%c\n", opt);
break;
case 'f':
printf("关联值:%s\n", optarg);//关联值存储在外部变量optarg里
break;
case '?':
printf("无法识别的选项:%c\n", optopt);//无法识别的选项存储在optopt里
break;
case ':':
printf("选项需要一个关联值\n");
break;
}
}
//处理完所有选项后,输出剩余参数
for(;optind < argc; optind++)
printf("参数:%s\n", argv[optind]);
exit(0);
}
运行:
root@ubuntu:/home/CPP# ./opt -i -f draft.txt -a -l -x -y "hello" "world"
参数:i
关联值:draft.txt
参数:a
参数:l
./opt: invalid option -- 'x'//stderr信息,无法识别的选项,由getopt自己输出
无法识别的选项:x
./opt: invalid option -- 'y'
无法识别的选项:y
参数:hello
参数:world
3.getopt_long
支持长选项"–",比如:ls --help
#include <getopt.h>
int getopt_long(int argc,
char * const argv[],
const char *optstring,
const struct option *longopts,
int *longindex);
相比于getopt(),getopt_long()多了两个参数:longopts和longindex。
注意:getopt.h头文件必须和常量_GNU_SOURCE一起包含进来,该常量启用getopt_long功能。
参数const struct option *longopts描述了每个长选项并告诉getopt_long如何处理它们。
struct option {
const char *name;//长选项的名字。接受缩写,只要不和其它选项冲突。
int has_arg;//该选项是否带参数。0--不带参数,1--必须有1个参数,2--有一个 可选参数
int *flag;//设置NULL,表示找到该选项就返回getopt_long在val里的值;
//否则,返回0,将val的值写入flag指向的变量。
int val;//getopt_long为该选项返回的值
};
参数int *longindex是一个指针变量,可以作为optind的长选项版本使用。不使用可以设置为NULL。
代码示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#define _GNU_SOURCE
int main(int argc, char **argv)
{
int opt;
struct option longopts[] = {
{"initialize", 0, NULL, 'i'},
{"file", 1, NULL, 'f'},
{"all", 0, NULL, 'a'},
{"list", 0, NULL, 'l'},
{0, 0, 0, 0},
};
while((opt = getopt_long(argc, argv, "if:al", longopts, NULL)) != -1)
{
switch(opt)
{
case 'i':
case 'a':
case 'l':
printf("参数:%c\n", opt);
break;
case 'f':
printf("关联值:%s\n", optarg);
break;
case '?':
printf("无法识别的选项:%c\n", optopt);
break;
case ':':
printf("选项需要一个关联值\n");
break;
}
}
for(;optind < argc; optind++)
printf("参数:%s\n", argv[optind]);
exit(0);
}
运行:
root@ubuntu:/home/CPP# ./opt --list --all -f draft.txt "hello"
参数:l
参数:a
关联值:draft.txt
参数:hello
运行:
root@ubuntu:/home/CPP# ./opt --list --all -f draft.txt "hello"
参数:l
参数:a
关联值:draft.txt
参数:hello