Command Line Arguments
命令行参数让C程序能够接收外部输入,使程序更加灵活和实用。掌握命令行参数处理是编写专业级C程序的基础技能:
命令行参数是程序启动时从命令行传递给程序的数据。它们让用户可以在不修改源代码的情况下改变程序的行为。
int main(int argc, char *argv[]) {
// argc: argument count(参数个数)
// argv: argument vector(参数向量/数组)
printf("程序接收到 %d 个参数\n", argc);
for (int i = 0; i < argc; i++) {
printf("argv[%d] = \"%s\"\n", i, argv[i]);
}
return 0;
}
argc 是一个整数,表示传递给程序的参数总数,包括程序名本身。
// 示例:./program hello world
// argc = 3(程序名 + 2个参数)
int main(int argc, char *argv[]) {
printf("参数总数: %d\n", argc); // 输出: 参数总数: 3
if (argc < 2) {
printf("用法: %s <参数1> [参数2] ...\n", argv[0]);
return 1; // 错误退出
}
return 0;
}
argv 是一个字符串数组,每个元素都是一个指向C字符串的指针。
命令:./calculator 15 + 25
argc = 4
所有命令行参数都是字符串!即使输入数字,也需要使用 atoi()、atof() 等函数转换为数值类型。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
printf("程序名: %s\n", argv[0]);
printf("参数个数: %d\n", argc - 1); // 减去程序名
// 遍历所有参数(跳过程序名)
for (int i = 1; i < argc; i++) {
printf("参数 %d: %s\n", i, argv[i]);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("用法: %s <数字1> <数字2>\n", argv[0]);
return 1;
}
// 转换字符串为整数
int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);
printf("%d + %d = %d\n", num1, num2, num1 + num2);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// 检查字符串是否为有效数字
int is_valid_number(const char *str) {
if (str == NULL || *str == '\0') {
return 0; // 空字符串
}
// 允许负号
if (*str == '-') {
str++;
}
// 检查每个字符是否为数字
while (*str) {
if (!isdigit(*str)) {
return 0;
}
str++;
}
return 1;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("用法: %s <数字>\n", argv[0]);
return 1;
}
if (!is_valid_number(argv[1])) {
printf("错误: '%s' 不是有效数字\n", argv[1]);
return 1;
}
int number = atoi(argv[1]);
printf("您输入的数字是: %d\n", number);
printf("它的平方是: %d\n", number * number);
return 0;
}
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
int verbose = 0; // 详细输出标志
int help = 0; // 帮助标志
char *filename = NULL;
// 解析选项
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
verbose = 1;
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
help = 1;
} else if (argv[i][0] != '-') {
// 不以 '-' 开头的参数视为文件名
filename = argv[i];
} else {
printf("未知选项: %s\n", argv[i]);
return 1;
}
}
if (help) {
printf("用法: %s [选项] <文件名>\n", argv[0]);
printf("选项:\n");
printf(" -v, --verbose 详细输出\n");
printf(" -h, --help 显示帮助\n");
return 0;
}
if (filename == NULL) {
printf("错误: 请指定文件名\n");
return 1;
}
if (verbose) {
printf("处理文件: %s\n", filename);
}
// 处理文件的代码...
printf("文件 '%s' 处理完成\n", filename);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
int count = 1; // 默认计数
char *output = NULL; // 输出文件
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-n") == 0) {
// 下一个参数应该是数字
if (i + 1 < argc) {
count = atoi(argv[i + 1]);
i++; // 跳过已处理的参数
} else {
printf("错误: -n 选项需要一个数值\n");
return 1;
}
} else if (strcmp(argv[i], "-o") == 0) {
// 下一个参数应该是输出文件名
if (i + 1 < argc) {
output = argv[i + 1];
i++; // 跳过已处理的参数
} else {
printf("错误: -o 选项需要一个文件名\n");
return 1;
}
}
}
printf("重复次数: %d\n", count);
if (output) {
printf("输出文件: %s\n", output);
} else {
printf("输出到标准输出\n");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc != 4) {
printf("用法: %s <数字1> <操作符> <数字2>\n", argv[0]);
printf("操作符: +, -, *, /\n");
return 1;
}
double num1 = atof(argv[1]);
char *operator = argv[2];
double num2 = atof(argv[3]);
double result;
if (strcmp(operator, "+") == 0) {
result = num1 + num2;
} else if (strcmp(operator, "-") == 0) {
result = num1 - num2;
} else if (strcmp(operator, "*") == 0) {
result = num1 * num2;
} else if (strcmp(operator, "/") == 0) {
if (num2 == 0) {
printf("错误: 除数不能为零\n");
return 1;
}
result = num1 / num2;
} else {
printf("错误: 不支持的操作符 '%s'\n", operator);
return 1;
}
printf("%.2f %s %.2f = %.2f\n", num1, operator, num2, result);
return 0;
}
// 使用示例:
// $ ./calculator 15.5 + 8.3
// 15.50 + 8.30 = 23.80
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("用法: %s [选项] <文件名1> [文件名2] ...\n", argv[0]);
printf("选项:\n");
printf(" -c 统计字符数\n");
printf(" -l 统计行数\n");
printf(" -w 统计单词数\n");
return 1;
}
int count_chars = 0, count_lines = 0, count_words = 0;
int file_start = 1; // 文件名开始的索引
// 解析选项
for (int i = 1; i < argc && argv[i][0] == '-'; i++) {
if (strcmp(argv[i], "-c") == 0) {
count_chars = 1;
} else if (strcmp(argv[i], "-l") == 0) {
count_lines = 1;
} else if (strcmp(argv[i], "-w") == 0) {
count_words = 1;
} else {
printf("未知选项: %s\n", argv[i]);
return 1;
}
file_start++;
}
// 如果没有指定选项,默认统计所有
if (!count_chars && !count_lines && !count_words) {
count_chars = count_lines = count_words = 1;
}
// 处理每个文件
for (int i = file_start; i < argc; i++) {
FILE *file = fopen(argv[i], "r");
if (file == NULL) {
printf("错误: 无法打开文件 '%s'\n", argv[i]);
continue;
}
int chars = 0, lines = 0, words = 0;
int in_word = 0;
int c;
while ((c = fgetc(file)) != EOF) {
chars++;
if (c == '\n') {
lines++;
}
if (c == ' ' || c == '\t' || c == '\n') {
in_word = 0;
} else if (!in_word) {
words++;
in_word = 1;
}
}
fclose(file);
printf("%s: ", argv[i]);
if (count_lines) printf("%d 行 ", lines);
if (count_words) printf("%d 单词 ", words);
if (count_chars) printf("%d 字符", chars);
printf("\n");
}
return 0;
}
int main(int argc, char *argv[]) {
// 1. 检查参数个数
if (argc < 2) {
fprintf(stderr, "用法: %s <参数>\n", argv[0]);
return 1;
}
// 2. 验证参数有效性
if (!is_valid_input(argv[1])) {
fprintf(stderr, "错误: 无效输入 '%s'\n", argv[1]);
return 1;
}
// 3. 进行实际处理,捕获错误
if (process_input(argv[1]) != 0) {
fprintf(stderr, "错误: 处理失败\n");
return 1;
}
return 0; // 成功
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for getopt
int main(int argc, char *argv[]) {
int opt;
int verbose = 0;
char *output_file = NULL;
int count = 1;
// 解析选项:v 无参数,o: 需要参数,n: 需要参数
while ((opt = getopt(argc, argv, "vo:n:h")) != -1) {
switch (opt) {
case 'v':
verbose = 1;
break;
case 'o':
output_file = optarg; // optarg 包含选项的参数
break;
case 'n':
count = atoi(optarg);
break;
case 'h':
printf("用法: %s [-v] [-o 输出文件] [-n 计数] 文件名\n", argv[0]);
return 0;
case '?':
// getopt 会自动打印错误信息
return 1;
}
}
// 处理非选项参数
for (int i = optind; i < argc; i++) {
printf("处理文件: %s\n", argv[i]);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
// 从环境变量获取默认值
char *default_editor = getenv("EDITOR");
if (default_editor == NULL) {
default_editor = "vi"; // 默认编辑器
}
char *editor = default_editor;
// 命令行参数可以覆盖环境变量
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-e") == 0 && i + 1 < argc) {
editor = argv[i + 1];
i++;
}
}
printf("使用编辑器: %s\n", editor);
return 0;
}
命令行参数是C程序与外界交互的重要接口。掌握了这些技能,你就能编写出真正实用的命令行工具和应用程序。