Если все, что вы ищете, это быстрый и грязный способ достижения легко масштабируемого списка параметров, вы можете попробовать что-то в следующих строках: Он имеет дополнительное преимущество, что вы можете определить значения по умолчанию для дополнительных параметров и включить эти значения по умолчанию в распечатку. Это также означает, что когда вы хотите добавить дополнительные обязательные или необязательные аргументы, вам просто нужно добавить их в список в методах DefineRequiredArgs
или DefineOptionalArgs
, и у вас есть доступ к ним в других местах.
// multi_option_helper.cpp
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
void function_to_call(std::vector<std::vector<std::string> > &req_args,
std::vector<std::vector<std::string> > &opt_args,
int num1 = 1,
int num2 = 2
)
{
// do fancy stuff here
// Print required options
std::cout << "Required Options:\n" ;
for (int i=0; i<req_args.size(); i++) {
std::cout << "\t" << req_args[i][0] << " = " << req_args[i][1] << std::endl;
}
// Print optional options
std::cout << "Optional Options:\n" ;
for (int i=0; i<opt_args.size(); i++) {
std::cout << "\t" << opt_args[i][0] << " = " << opt_args[i][1] << std::endl;
}
}
std::vector<std::vector<std::string> > DefineRequiredArgs()
{
// Define the required arguments
std::vector<std::vector<std::string> > req_args ;
/* pre-c++11 way of doing it */
// Define a generic vector of strings
std::vector<std::string> arg(2) ;
arg[1] = "" ;
arg[0] = "1st_argument" ;
req_args.push_back(arg) ;
arg[0] = "2nd_argument" ;
req_args.push_back(arg) ;
arg[0] = "3rd_argument" ;
req_args.push_back(arg) ;
arg[0] = "4th_argument" ;
req_args.push_back(arg) ;
// ... continue this process as many times as needed
/* post-c++11 way of doing it
req_args.push_back({"1st_argument", ""}) ;
req_args.push_back({"2nd_argument", ""}) ;
req_args.push_back({"3rd_argument", ""}) ;
req_args.push_back({"4th_argument", ""}) ;
*/
return req_args ;
}
std::vector<std::vector<std::string> > DefineOptionalArgs()
{
// Define the required arguments
std::vector<std::vector<std::string> > opt_args ;
// pre-c++11
std::vector<std::string> arg(2) ;
arg[1] = "" ;
arg[0] = "5th_argument" ;
arg[1] = "foo" ;
opt_args.push_back(arg) ;
arg[0] = "6th_argument" ;
arg[1] = "bar" ;
opt_args.push_back(arg) ;
arg[0] = "7th_argument" ;
arg[1] = "521600" ;
opt_args.push_back(arg) ;
arg[0] = "8th_argument" ;
arg[1] = "86" ;
opt_args.push_back(arg) ;
arg[0] = "9th_argument" ;
arg[1] = "somethingelse" ;
opt_args.push_back(arg) ;
// ... continue this process as many times as needed
/* c++11 alternative
opt_args.push_back({"5th_argument", "foo"}) ;
opt_args.push_back({"6th_argument", "bar"}) ;
opt_args.push_back({"7th_argument", "521600"}) ;
opt_args.push_back({"8th_argument", "86"}) ;
opt_args.push_back({"9th_argument", "somethingelse"}) ;
*/
return opt_args ;
}
int main(int argc, char** argv)
{
// Get the required options
std::vector<std::vector<std::string> > req_args = DefineRequiredArgs() ;
// Get the optionsl options
std::vector<std::vector<std::string> > opt_args = DefineOptionalArgs() ;
if(argc < req_args.size()+1) {
std::cerr << "Usage: \n\t" << argv[0] ;
// Print the required arguments
for (int i=0; i<req_args.size(); i++) {
std::cerr << "\n\t" << req_args[i][0] ;
}
// Print the optional arguments
for (int i=0; i<req_args.size(); i++) {
std::cerr << "\n\t" << opt_args[i][0]
<< " (optional Default=" << opt_args[i][1] << ")" ;
}
std::cerr << std::endl;
} else {
// Fill the required options
int opt_counter(1) ;
while ((opt_counter <= req_args.size())) {
req_args[opt_counter-1][1] = std::string(argv[opt_counter]) ;
opt_counter++ ;
}
// Now fill the optional options
int offset(req_args.size()+1) ; // Note the additional offset of '1'
while ((opt_counter < argc)) {
opt_args[opt_counter-offset][1] = std::string(argv[opt_counter]) ;
opt_counter++ ;
}
// Fill num1 and num2
int num1, num2 ;
std::stringstream stream ;
stream << opt_args[2][1] << ' ' << opt_args[3][1] ;
stream >> num1 >> num2 ;
/* c++11 alternative
int num1 = std::stoi(opt_args[2][1]) ;
int num2 = std::stoi(opt_args[3][1]) ;
*/
// Now call the helper function
function_to_call(req_args, opt_args, num1, num2) ;
}
return 0;
}
Теперь, когда вы работаете с меньшим, чем требуемое количество вариантов вы получите распечатку:
Usage:
./multi_option_helper
1st_argument
2nd_argument
3rd_argument
4th_argument
5th_argument (optional Default=foo)
7th_argument (optional Default=521600)
8th_argument (optional Default=86)
9th_argument (optional Default=somethingelse)
Обратите внимание, что поскольку тег только «C++», а не «C++ 11 «Я включил только код, который будет компилировать, делая g++ multi_option_helper.cpp -o multi_option_helper
, однако есть несколько альтернатив C++ 11, которые упрощают работу.
С другой стороны, если вы ищете более то, что вы ищете, то, что позволяет вам создавать именованные параметры (например, --Arg1=arg1_val
), вы можете взглянуть на «GetOpt». Одним из преимуществ этого является способность вашего пользователя передавать параметры в любом порядке. Вы также можете создать вариант справки (обычно это опция -h
или --help
в некоторых программах).
Личное примечание: Я стараюсь избегать использования методов BOOST, потому что они добавляют дополнительную зависимость к моему коду. Либо я должен включать заголовочные файлы в свой пакет (я не уверен, какое лицензирование BOOST использует, так что это может быть даже не законным), или требуется, чтобы пользователь заходил и загружал их, а затем загружал библиотеку самостоятельно. Вот почему я предпочитаю GetOpt, так как большинство людей, использующих современные компиляторы, уже должны иметь к нему доступ. Я также разработал собственный класс обработчика параметров командной строки, чтобы упростить определение и использование параметров командной строки. Проверьте это here, если вам интересно.
Первое, что приходит на ум - это цикл и std :: vector '. –
Вы должны рассмотреть реализацию 'get options' (возможно, gnu getopt или boost :: options) –
Или иметь локальные переменные, которые содержат значения по умолчанию для пропущенных параметров (и будут изменены эти параметры переданы), тогда вы требуется только вызов функции. – 1201ProgramAlarm