在Linux程序开发中,处理命令行参数是常见需求。本文将深入探讨可变参数和选项的处理方法。
可变参数指的是程序运行时可以接受数量不固定的参数。在C语言中,主要通过以下方式实现:
#include <stdarg.h>
void example_func(int count, ...) {
va_list args;
va_start(args, count);
for(int i = 0; i < count; i++) {
int value = va_arg(args, int);
printf("%d ", value);
}
va_end(args);
}
#include <stdio.h>
#include <stdarg.h>
double average(int num, ...) {
va_list valist;
double sum = 0.0;
va_start(valist, num);
for (int i = 0; i < num; i++) {
sum += va_arg(valist, int);
}
va_end(valist);
return sum / num;
}
int main() {
printf("Average of 2, 3, 4, 5 = %.2f\n", average(4, 2, 3, 4, 5));
printf("Average of 5, 10, 15 = %.2f\n", average(3, 5, 10, 15));
return 0;
}
getopt
是POSIX标准中定义的处理命令行参数的函数。
#include <unistd.h>
int main(int argc, char *argv[]) {
int opt;
while ((opt = getopt(argc, argv, "ab:c:")) != -1) {
switch (opt) {
case 'a':
printf("Option a\n");
break;
case 'b':
printf("Option b with value '%s'\n", optarg);
break;
case 'c':
printf("Option c with value '%s'\n", optarg);
break;
default:
fprintf(stderr, "Usage: %s [-a] [-b value] [-c value]\n", argv[0]);
return 1;
}
}
return 0;
}
对于需要长选项的程序,可以使用getopt_long
:
#include <getopt.h>
int main(int argc, char *argv[]) {
int opt;
static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{"file", required_argument, 0, 'f'},
{0, 0, 0, 0}
};
while ((opt = getopt_long(argc, argv, "hvf:", long_options, NULL)) != -1) {
switch (opt) {
case 'h':
printf("Help message\n");
break;
case 'v':
printf("Version 1.0\n");
break;
case 'f':
printf("File specified: %s\n", optarg);
break;
default:
fprintf(stderr, "Usage: %s [-h] [-v] [--file filename]\n", argv[0]);
return 1;
}
}
return 0;
}
#include <argp.h>
const char *argp_program_version = "program 1.0";
const char *argp_program_bug_address = "<bug@example.com>";
static struct argp_option options[] = {
{"verbose", 'v', 0, 0, "Produce verbose output"},
{"output", 'o', "FILE", 0, "Output to FILE instead of stdout"},
{0}
};
static error_t parse_opt(int key, char *arg, struct argp_state *state) {
switch (key) {
case 'v':
printf("Verbose mode enabled\n");
break;
case 'o':
printf("Output file: %s\n", arg);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp argp = {options, parse_opt, 0, 0};
int main(int argc, char **argv) {
argp_parse(&argp, argc, argv, 0, 0, 0);
return 0;
}
一致性:遵循GNU/Linux命令行工具的通用约定
-h
--help
--
文档:提供清晰的--help
输出
错误处理:对无效参数给出明确提示
参数顺序:通常选项在前,非选项参数在后
国际化:考虑使用gettext等工具支持多语言
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <stdbool.h>
#define PROGRAM_VERSION "1.0"
void print_help(const char *prog_name) {
printf("Usage: %s [OPTIONS] [FILE...]\n", prog_name);
printf("Options:\n");
printf(" -h, --help Display this help message\n");
printf(" -v, --version Display version information\n");
printf(" -o, --output Specify output file\n");
printf(" -q, --quiet Suppress normal output\n");
}
int main(int argc, char *argv[]) {
bool quiet = false;
char *output_file = NULL;
static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{"output", required_argument, 0, 'o'},
{"quiet", no_argument, 0, 'q'},
{0, 0, 0, 0}
};
while (1) {
int option_index = 0;
int c = getopt_long(argc, argv, "hvo:q", long_options, &option_index);
if (c == -1) break;
switch (c) {
case 'h':
print_help(argv[0]);
return 0;
case 'v':
printf("%s version %s\n", argv[0], PROGRAM_VERSION);
return 0;
case 'o':
output_file = optarg;
break;
case 'q':
quiet = true;
break;
default:
print_help(argv[0]);
return 1;
}
}
if (!quiet) {
printf("Processing files...\n");
if (output_file) {
printf("Output will be written to: %s\n", output_file);
}
}
for (int i = optind; i < argc; i++) {
if (!quiet) {
printf("Processing file: %s\n", argv[i]);
}
// 实际处理文件的代码
}
return 0;
}
通过掌握这些技术,您可以构建出符合Linux惯例、用户友好的命令行程序。