前提知识:main的argc和argv是什么
argc和argv是程序的入口函数main的参数,它们用于接收和解析命令行传递给程序的参数。
比如我们在命令行中运行一个程序时
./test -a value1 -b value2 a.cpp
对于上述这个命令行,操作系统会将命令行拆分为字符串数组,并对argc和argv进行设置,然后将argc和argv传递给可执行文件test的入口main函数。
agrc:参数总数,对于上面这个命令行会被拆分成6个部分,因此argc为6argv:数组内容,argv[0]为”./test”、argv[1]为”-a”..........argv[5]为”a.cpp”
<getopt.h>中的常用函数
getopt
函数原型:
int getopt(int argc, char argv[], const char* optstring);
参数:
argc:命令行的参数量(一般由main提供,也可以自己传入)
argv:命令行的的参数数组(一般由main提供,也可以自己传入)
optstring:一个字符串,用于定义有效的选项及其参数需求
每个字符表示一个选项,例如a表示选项-a
如果一个选项需要参数,则在字符后添加:例如b:表示-b 需要参数
如果选项是可选的(仅GNU扩展支持),使用:: 例如c::
返回值:
成功解析则返回当前选项的字符,比如返回a表示-a
如果解析完毕返回-1
如果遇到无效的选项返回?,并设置全局变量optopt为无效选项的字符
示例:
getopt_long
解析命令行参数中的长选项,例如 - -option,并可结合短选项一起使用
函数原型:
int getopt_long(int argc, char* const argv[], const char* optstring
const struct option* longopts, int* longindex);
参数:
argc:命令行参数数量
argv:命令行参数数组
optstring:定义短选项及其参数需求(与getopt相同)
longopts:指向一个struct option数组,用于定义长选项的属性
longindex:指向一个整数,用于存储当前被解析的长选型在longopts数组中的索引
结构体:option
struct option {const char* name; 长选型的名称(如”help”)int has_arg; 参数类型:0表示无参数,1表示需要参数,2表示可选参数int* flag; 如果非NULL,则返回0并设置*flag为val,否则返回valint val; 长选项的返回值(如果flag为NULL)
}
注意:该struct option数组必须以一个空项的option结构体结束
static struct option long_options[] = {{"help", no_argument, nullptr, 'h'},{"output", required_argument, nullptr, 'o'},{"version", no_argument, nullptr, 'v'},{nullptr, 0, nullptr, 0 } //结束标志
};
返回值:
如果flag为NULL,返回val
如果flag非NULL,返回0,并将*flag设置为val
如果加载完毕返回-1
如果遇到无效选项,返回?
示例:
<getopt.h>中的全局变量
optind
int optind
通常初始化为1,指向argv[1](跳过程序名)
在调用getopt或getopt_long时,optind会自动递增,用于跟踪解析进度
当所有选项解析完成后,optind会指向第一个非选项参数(或超出argv范围)
示例:
首先getind会被初始化为1,在getopt时optind会随着解析到有效选项而自增,由于有两个有效项,因此会自增到3。
optopt
表示解析过程中遇到的未定义选项或选项缺少参数时的选项字符
int optopt
如果命令行的选项未在optstring中定义或者选项定义时指明了需要参数,但在命令行中没有为该选项指定参数,则getopt返回’?’,并将错误选项字段存储在optopt中
示例:
opterr
控制getopt是否自动打印错误信息
默认值为1,表示启用错误信息输出
如果opterr为非0值,当解析遇到错误时,getopt会打印标准错误信息
设置opterr = 0可以禁用此行为,让程序自行处理错误
optarg
存储当前选项的参数值(如果需要参数)
char* optarg
如果某选项需要参数(由optstring中的:指定),optarg会指向该参数值。
如果选项中没有参数或解析错误,则optarg为NULL
示例:
全局变量总结:
<getopt.h>使用示例
#include <iostream>
#include <getopt.h> // getopt_long
#include <string>
#include <vector>int main(int argc, char* argv[]) {std::string inputFile;std::string outputFile;std::string mode = "default";bool verbose = false;// 禁止 getopt 自动输出错误信息opterr = 0;// 定义长选项结构体const struct option long_options[] = {{"input", required_argument, nullptr, 'i'},{"output", required_argument, nullptr, 'o'},{"mode", required_argument, nullptr, 'm'},{"verbose", no_argument, nullptr, 'v'},{"help", no_argument, nullptr, 'h'},{nullptr, 0, nullptr, 0} };int opt;int long_index = 0;// 开始解析参数while ((opt = getopt_long(argc, argv, "i:o:m:vh", long_options, &long_index)) != -1) {switch (opt) {case 'i':inputFile = optarg;break;case 'o':outputFile = optarg;break;case 'm':mode = optarg;break;case 'v':verbose = true;break;case 'h':std::cout << "Usage: " << argv[0] << " [OPTIONS] file1 file2 ...\n"<< " -i, --input <file> Input file\n"<< " -o, --output <file> Output file\n"<< " -m, --mode <mode> Processing mode (default/custom)\n"<< " -v, --verbose Enable verbose output\n"<< " -h, --help Show this help message\n";return 0;case '?':std::cerr << "Unknown option: " << static_cast<char>(optopt) << "\n";return 1;}}// 输出所有选项结果std::cout << "Input File : " << inputFile << "\n"; // ← 输入文件std::cout << "Output File: " << outputFile << "\n"; // ← 输出文件std::cout << "Mode : " << mode << "\n"; // ← 模式std::cout << "Verbose : " << (verbose ? "Yes" : "No") << "\n"; // ← 是否开启 verbose// 输出剩余的非选项参数(比如要处理的多个文件)std::vector<std::string> files;for (int i = optind; i < argc; ++i) {files.emplace_back(argv[i]);}std::cout << "Remaining files to process: \n";for (const auto& file : files) {std::cout << " " << file << "\n"; // ← 非选项参数(如 a.cpp b.cpp 等)}// 这里你可以根据 inputFile/outputFile/mode/files 做实际文件处理// (此处略去实现逻辑)return 0;
}
命令行执行:
./fileproc -i config.txt --output result.log -m fast --verbose main.cpp util.cpp
程序输出:
Input File : config.txt
Output File: result.log
Mode : fast
Verbose : Yes
Remaining files to process: main.cpputil.cpp