Как использовать 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"
Другие вопросы по тегам