Как использовать boost program_options для чтения целочисленного массива?
Я использую Ubuntu и Boost v1.50.
Ранее я использовал boost program_options для передачи набора параметров в программу, например, так:
#!/bin/bash
./prog --arg1 1 --arg2 "2" --arg3 {1,2,3} --arg4 {1,2} --arg5 5
Так что я имею дело со смесью отдельных целых чисел, строк и целочисленных массивов. Это работало нормально.
Однако после "улучшения" кода путем введения локальных переменных в bash, у меня есть:
#!/bin/bash
a1=1
a2="2"
a3={1,2,3}
a4={1,2}
a5=5
./prog --arg1 $a1 --arg2 $a2 --arg3 $a3 --arg4 $a4 --arg5 $a5
Выполнение этого приводит к ошибке:
error: the argument ('{1,2,3}') for option '--arg3' is invalid
Я установил повышение program_options как это:
namespace po = boost::program_options;
using namespace std;
try{
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("arg1", po::value<int>(&arg1)->required(), "doc1")
("arg2", po::value<string>(&arg2)->default_value("test"), "doc2")
("arg3", po::value<vector<int> >(&arg3)->multitoken(), "doc3")
("arg4", po::value<vector<int> >(&arg4)->multitoken(), "doc4")
("arg5", po::value<int>(&arg5)->default_value(1), "doc5")
;
po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);
if(vm.count("help")) cout << desc << "\n";
}
catch(exception& e){
cerr << "error: " << e.what() << "\n";
errorflag=1;
}
catch(...){
cerr << "Exception of unknown type!\n";
errorflag=1;
}
Где я неправ? Мультитокен не подходит в этом контексте? Что я могу использовать вместо этого? Разве нельзя читать целочисленные массивы?
Я попытался опустить мультитокен, но потом тоже не получилось. Использование кавычек вокруг локальной переменной в скрипте bash также не помогает.
Если я изменю ввод массива с {a, b, c} на "a b c", это нормально. Тем не менее, у меня уже есть большое количество записей в другом формате, и я хотел бы продолжать использовать его, так как другие программы также зависят от него.
Я думаю, что это должно быть выполнимо, так как он работал без локальных переменных. Кто-нибудь знает как?
РЕДАКТИРОВАТЬ: я ошибся. "a b c" НЕ работает как ввод:(
РЕДАКТИРОВАТЬ 2: я нашел небольшой обходной путь: я конвертирую {a,b,c} -> a b c, используя
argnew=`echo ${arg:1:-1} | tr ',' ' '`
и подача его в программу работает нормально. Это лучшее решение?
1 ответ
Изменение исходного сценария для добавления -x
Вариант отладки bash, вот так:
#!/bin/bash -x
./prog --arg1 1 --arg2 "2" --arg3 {1,2,3} --arg4 {1,2} --arg5 5
и затем запустить это показывает этот вывод:
+ ./prog --arg1 1 --arg2 2 --arg3 1 2 3 --arg4 1 2 --arg5 5
Так что ваши фигурные скобки не работают так, как вы думаете, потому что обработка командной строки bash расширяет их перед вызовом ./prog
,
Вы можете заставить его работать, если в вашем втором сценарии, если вы измените назначения для a3
а также a4
быть таким:
a3='1 2 3'
a4='1 2'
а затем двойные кавычки всех ваших переменных при вызове ./prog
:
./prog --arg1 "$a1" --arg2 "$a2" --arg3 "$a3" --arg4 "$a4" --arg5 "$a5"