初识c语言时,我一直将main函数写作 int main(void),但随着学习的深入,我了解到main函数身为一个函数,当然也可以接收输入的参数,它的参数就是进程开始时输入的命令。所以main函数的完整形式应该写作:
int main(int argc,char *argv[]),其中argc是一个int型变量,储存命令参数的个数,argv是一个指针数组名
(所以char *argv[] 也可以写作char **argv),其中保存着命令参数字符串。
可以写一个小程序打印传入main函数的命令参数:
test.c
#include
int main(int argc,char *argv[])
{
int count;
while(count < argc){
printf("argv[%d]:%s\n",count,argv[count]);
count++;
}
return 0;
}
将test.c编译运行,并在运行时随意添加一些参数。
从运行结果可以看到,运行时输入的命令被保存在argv[]中。
需要注意的是argv[]的第一个元素argv[0]默认保存的是程序名,而且argv[]是以NULL结尾的,也就是说当有n个命令参数被保存在argv[]中时,数组中第n+1个元素是NULL,即argv[argc]是NULL。将test.c稍修改一下即可验证:
test.c
#include
int main(int argc,char *argv[])
{
int count;
while(count < argc){
printf("argv[%d]:%s\n",count,argv[count]);
count++;
}
printf("argv[%d]:%s\n",count,argv[count]);
return 0;
}
当然,只给main函数传递参数是不够的,我们还需要在函数里分析参数,下面简要介绍常用的命令参数分析函数getopt()。
函数原型:
#include
extern char *optarg;
extern int optind, // 初始化值为1,下一次调用getopt时,从optind存储的位置重新开始检查选项,也就是从下一个'-'的选项开始。
extern int opterr, // 初始化值为1,当opterr=0时,getopt不向stderr输出错误信息。
extern int optopt; // 当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt中,getopt返回’?’。
假设现在a.out是一个可以接受 "-a" "-b" "-f" 选项的程序,其中"-a"选项必须跟参数值,"-b"选项不需要参数值,"-f"选项可跟可不跟参数值。用getopt()函数分析命令行参数的代码如下:
#include
#include
#include
int main(int argc,char *argv[])
{
char ch;
int count=0;
opterr=0;
while((ch=getopt(argc,argv,"a:bf::")) != -1){
switch(ch){
case 'a':
printf("optinon a:%s\n",optarg);
break;
case 'b':
printf("optinon b:%s\n",optarg);
break;
case 'f':
printf("option f:%s\n",optarg);
break;
default:
printf("other option:%c\n",ch);
break;
}
}
return 0;
}
编译后运行输入 ./a.out -a 123 -b asdf -c -f 运行结果如下:
"-a"选项需要一个参数值,getopt()将"123"存入optarg。"-b"选项不需要参数值,故忽略命令中"-b"后面的参数值,optarg输出为NULL。optstring中没有"-c"选项,getopt()返回'?'。"-f"选项后面没有参数值,optarg输出NULL。
从结果可以看出,每次调用getopt()函数会依次检查命令参数,根据optstring字符串查找选项,返回选项的字符(如"-a"选项返回'a')。并检查是否带参数值,如果有参数值则将其存入optarg中,如果在处理期间遇到了不符合optstring指定的选项,getopt()将返回'?',同时打印一个错误信息,并将optarg置为NULL,如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。