命令行传参

命令行传参函数原型为int main(int argc, char *argv[])或者int main(int argc, char **argv),其中argv是参数个数,argv是实际传参。

#include <stdio.h>

int main(int argc, char *argv[])
{
for(int i = 0; i < argc; i++)
printf("No.%d parm is %s\n", i, argv[i]);

return 0;
}

编译运行

由运行结果可以看到,第一个参数为程序名称,在处理命令行参数的时候要注意从第二个参数开始才是真正需要处理的参数

$gcc -o test test.c 
$./test hello world
No.0 parm is ./test
No.1 parm is hello
No.2 parm is world

命令行参数处理函数

查询man手册,c语言提供了下面几个命令行参数处理函数,下面给出函数原型和所在头文件。

#include <unistd.h>
#include <getopt.h>
extern char *optarg;
extern int optind, opterr, optopt;
int getopt (int ___argc, char *const *___argv, const char *__shortopts);
int getopt_long (int ___argc, char *__getopt_argv_const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind);

选项列表规则

例如,+ab:c::

类型 描述
+ 默认会重新排列参数,将不以’-‘开头的参数移动到参数列表的末尾,’+’告诉函数不要打乱顺序
单字符’a’ 表示选项没有参数
b: 必须跟一个参数
c:: 可选参数,如果有参数,不能加空格-c100,不能是-c 100

getopt

函数说明

描述:解析短选项命令行参数,例如 -h。无法解析长选项,如--help
参数:argc:参数个数,argv:参数列表,__shortopts:短选项列表
返回值:成功返回选项字符,解析完成返回-1.
行为:每次调用getopt,如果成功解析到有效选项,会将当前选项的指针赋值给optarg变量,将下一个argv指针的索引赋值给optind

示例

#include <stdio.h>
#include <unistd.h>

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

// 解析选项
while ((opt = getopt(argc, argv, "hv:o:")) != -1)
{
switch (opt)
{
case 'h':
printf("Usage: %s [-h] [-v] [-o output]\n", argv[0]);
break;
case 'v':
printf("Verbose mode enabled\n");
break;
case 'o':
printf("Output file: %s\n", optarg);
break;
case '?':
fprintf(stderr, "Usage: %s [-h] [-v] [-o output]\n", argv[0]);
return 1;
default:
abort();
}
}

// 打印未处理的参数
printf("Remaining arguments:\n");
for (int i = optind; i < argc; i++) {
printf("%s\n", argv[i]);
}

return 0;
}

getopt_long

函数说明

描述:增加长选项参数解析功能。例如--help

struct option
{
const char *name;
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};

参数:__longopts:指向 struct option 结构体数组的指针用于定义长选项。__longind:会将长选项的索引存储在这里。这个索引值表示当前处理的长选项在 __longopts 数组中的位置。

示例

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int main(int argc, char *argv[])
{
int opt;
int option_index = 0;

// 定义长选项
static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"output", required_argument, NULL, 'o'},
{"verbose", no_argument, NULL, 'v'},
{0, 0, 0, 0}
};

// 解析选项
while ((opt = getopt_long(argc, argv, "hvo:", long_options, &option_index)) != -1)
{
switch (opt)
{
case 'h':
printf("Usage: %s [--help] [--verbose] [--output file]\n", argv[0]);
break;
case 'v':
printf("Verbose mode enabled\n");
break;
case 'o':
printf("Output file: %s\n", optarg);
break;
case '?':
fprintf(stderr, "Usage: %s [--help] [--verbose] [--output file]\n", argv[0]);
return 1;
default:
abort();
}
}

// 打印未处理的参数
printf("Remaining arguments:\n");
for (int i = optind; i < argc; i++)
{
printf("%s\n", argv[i]);
}

return 0;
}