程序参数argc和argv

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值