什么是命令行参数?本人是c++菜鸟

2025-04-23 12:21:56
推荐回答(2个)
回答1:

可以通过在程序的main()函数中添加形式参数来接收程序在启动时从命令行中获得的各个命令行参数,包括:程序名称、路径、当前环境变量和用户指定参数等。命令行参数由启动程序截获并传递给main()。

一个典型的命令行例子如:

Mycopy srcFile destFile

一个典型的main()例子如:

int main( int argc, char *argv[ ] , char *envp[ ] );

argc

指示数组指针argv中包含的参数个数,该整数总是大于等于1。

argv

一个以NULL以为的字符串数组,存储用户输入的命令行参数。按照惯例,argv[0]为程序调用的命令,如c:\mycopy.exe;argv[1]为第一个命令行参数,直到argv[argc-1];argv[argc]总是NULL。

envp

存储执行当前程序的用户环境变量

#include

int main(int argCount,char * argValue[], char * envp[])

{

FILE* srcFile = 0, *destFile =0;

int ch = 0;

int i = 0;

if (argCount != 3){

printf("Usage:%s src-file-name dest-file-name\n",argValue[0]);

}else{

if((srcFile = fopen(argValue[1],"r")) == 0){

printf("Can not open source file\"%s\"!",argValue[1]);

}else{

if((destFile = fopen(argValue[2],"w")) ==0){

printf("Can not open destination file\"%s\"!",argValue[2]);

}else{

while((ch = fgetc(srcFile))!= EOF) fputc(ch,destFile);

printf("Successful to copy a file!\n");

fclose(srcFile);

fclose(destFile);

printf("%d command line parameters are got in program \n",argCount);

printf("All command line parameters are list here:\n");

while(envp[i]!=NULL){

printf("%s\n",argValue[i]);

i++;

}

i = 0;

printf("The variable set is list here:\n");

while(envp[i]!=NULL){

printf("%s\n",envp[i]);

i++;

}

return 0;

}

}

}

return 1;

}

回答2:

CLI(Command Line Interface)编程中很重要的一步,就是命令行参数的解析。对于初涉这一块的兄弟来说,argv, argc摆弄起来还是非常繁琐的。本文简单的介绍getopt相关几个命令行参数解析函数的用法,并搭上几个简单的实例,力求使读者能够基本掌握它的用法。

下面的几个API是从man 3 getopt中截取并简化。

这个函数初定义在unistd.h中,实现最基本的命令行参数解析功能,只支持象-a -d这样短参数格式,不支持象--color --dir这样的长参数格式。
int getopt(int argc, char * const argv[],
const char *optstring);

这个函数定义在getopt.h中,实现了长短参数混合解析。
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);

这个函数定义在getopt.h中,只支持长参数的解析。
int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);

在现实运用中,当然是中间一个函数用得最多,谁不想自己的CLI程序支持短参数的同时也支持长参数呢?

短参数的定义:
getopt使用optstring所指的字串作为短参数列表,象"1ac:d::"就是一个短参数列表。短参数的定义是一个'-'后面跟一个字母或数字,象-a, -b就是一个短参数。每个数字或字母定义一个参数。

其中短参数在getopt定义里分为三种:
1. 不带值的参数,它的定义即是参数本身
2. 必须带值的参数,它的定义是在参数本身后面再加一个冒号
3. 可选值的参数,它的定义是在参数本身后面加两个冒号

在这里拿上面的"1ac:d::"作为样例进行说明,其中的1,a就是不带值的参数,c是必须带值的参数,d是可选值的参数。
在实际调用中,'-1 -a -c cvalue -d', '-1 -a -c cvalue -ddvalue', '-1a -ddvalue -c cvalue'都是合法的。这里需要注意三点:
1. 不带值的参数可以连写,象1和a是不带值的参数,它们可以-1 -a分开写,也可以-1a或-a1连写。
2. 参数不分先后顺序,'-1a -c cvalue -ddvalue'和'-d -c cvalue -a1'的解析结果是一样的
3. 要注意可选值的参数的值与参数之间不能有空格,必须写成-ddvalue这样的格式,如果写成-d dvalue这样的格式就会解析错误。

getopt()的返回值:
getopt()每次调用会逐次返回命令行传入的参数
当没有参数的最后的一次调用时,getopt()将返回-1。
当解析到一个不在optstring里面的参数,或者一个必选值参数不带值时,返回'?'
当optstring是以':'开头时,缺值参数的情况下会返回':',而不是'?'

getopt()的出错信息:
使用getopt的时候,当参数有错的时候会经常出现一些我们不希望出现的出错信息。这是getopt通过stderr输出的错误信息。我们可以通过把opterr设成0来解决这个问题。

参数值的获取:
当参数后面带有值时,调用后会把值放入到optarg字符串里面;如果没有值时,这个字串将被置空。

getopt()的三种解析模式:
1. 默认情况下,getopt()会按照optstring定义的顺序进行参数解析,不在optstring定义的参数会返回?,然后把非参数的值放到argv队列的最后。
2. 当optstring以'+'开头定义时,getopt()会跳过所有不在optstring中的参数,并把他们都当作是非参数的值发到队列的最后。
3. 当optstring以'-'开头定义时,没看懂。。。。有空再看

例1:用getopt()实现短参数的解析。

#include
#include
void parse_arg(int argc, char *argv[])
{
int c;
opterr = 0;
while(1)
{
c = getopt_long (argc, argv, ":1ac:d::");
if (c == -1)
{
break;
}
switch(c)
{
case '1':
case 'a':
printf ("option %c\n", c);
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
if (optarg != NULL)
{
printf ("option d with value `%s'\n", optarg);
}
else
{
printf ("option d\n");
}
break;
case '?':
printf("unknown parameter: %c\n", optopt);
break;
case ':':
printf("need parameter: %c\n", optopt);
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
break;
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
{
printf ("%s ", argv[optind++]);
}
printf ("\n");
}
}

int main(int argc, char *argv[])
{
parse_arg(argc, argv);
return 0;
}

例2:用getopt_long()实现长短参数的混合解析。

不足之处:

getopt没有提供强制参数或可选参数列表的功能,只是提出了一种参数获取的方法。在实际使用中,在使用getopt解析参数过后,还必须对程序的参数进行存在性,或有效性验证,这仍然是一件很繁琐的事情。期待在以后的应用中能够很好的解决这个问题。

最后,getopt只是用一种既定的模式来进行了命令行参数的解析。既然是一种既定的模式,肯定就有它的缺陷。如果读者在实际运用中遇到一些getopt不能解决的地方,还是只有自己写方法来解析命令行参数。也许有朝一日会有一个比getopt更完美的命令行解析库出现