假设我有一个 main 函数,它基本上只是调用另一个函数作为程序的入口点。该函数(以及整个程序)有一些强制参数和一些可选参数:
#include <iostream>
#include <sstream>
void function_to_call(std::string arg1,
std::string arg2,
std::string arg3,
std::string arg4,
std::string arg5 = "foo",
std::string arg6 = "bar",
int num1 = 1,
int num2 = 2
)
{
// do fancy stuff here
}
int main(int argc, char** argv)
{
int num1, num2;
std::stringstream stream;
if( argc < 5 ) {
std::cerr << "Usage: \n\t" << argv[0]
<< "\n\t\t1st argument"
<< "\n\t\t2nd argument"
<< "\n\t\t3rd argument"
<< "\n\t\t4th argument"
<< "\n\t\t5th argument (optional)"
<< "\n\t\t6th argument (optional)"
<< "\n\t\t7th argument (optional)"
<< "\n\t\t8th argument (optional)"
<< "\n\t\t9th argument (optional)" << std::endl;
}
if( argc == 5 ) {
function_to_call( argv[1], argv[2], argv[3], argv[4] );
}
if( argc == 6 ) {
function_to_call( argv[1], argv[2], argv[3], argv[4], argv[5] );
}
if( argc == 7 ) {
function_to_call( argv[1], argv[2], argv[3], argv[4], argv[5], argv[6] );
}
if( argc == 8 ) {
stream << argv[7];
stream >> num1;
function_to_call( argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], num1 );
}
if( argc == 9 ) {
stream << argv[7] << ' ' << argv[8];
stream >> num1 >> num2;
function_to_call( argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], num1, num2 );
}
return 0;
}
if
链可以用 switch
替换,命令行可以通过使用 getopt
库或boost program_options
,但这并没有真正改变概念上的事情。
我是否缺少一种明显的方法来处理不同数量的参数?
最佳答案
命令行参数数组是null 终止,因此您可以像这样一次解析一个元素:
void function_to_call(std::string arg1,
std::string arg2,
std::string arg3,
int num1,
int num2
)
{
// do fancy stuff here
std::cout << "arg1: " << arg1 << '\n';
std::cout << "arg2: " << arg2 << '\n';
std::cout << "arg3: " << arg3 << '\n';
std::cout << "num1: " << num1 << '\n';
std::cout << "num2: " << num2 << '\n';
}
struct config
{
std::string arg1;
std::string arg2;
std::string arg3 = "wibble"; // set arg3 default here
int arg4 = 1; // set arg4 default here
int arg5 = 0; // set arg5 default here
};
config parse_command_params(char** argv)
{
config cfg;
if(!argv[1])
throw std::runtime_error("At least 2 args required");
cfg.arg1 = argv[1];
if(!argv[2])
throw std::runtime_error("At least 2 args required");
cfg.arg2 = argv[2];
// optional from here on
if(!argv[3])
return cfg;
cfg.arg3 = argv[3];
if(!argv[4])
return cfg;
cfg.arg4 = std::stoi(argv[4]);
if(!argv[5])
return cfg;
cfg.arg5 = std::stoi(argv[5]);
return cfg;
}
int main(int, char** argv)
{
try
{
config cfg = parse_command_params(argv);
function_to_call(cfg.arg1, cfg.arg2, cfg.arg3, cfg.arg4, cfg.arg5);
}
catch(std::exception const& e)
{
std::cerr << e.what() << '\n';
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
通过将参数存储在 struct
中,我可以使用它来设置可选参数的默认值,如果它们不存在于用户提供的参数中,则简单地忽略它们。
注意:编辑以包含@cmaster 将解析移动到专用函数的建议。
关于c++ - 处理 main 中的可选参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39550684/