Как использовать boost program_options для чтения целочисленного массива?

0

Я использую 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

Я настроил boost_options boost следующим образом:

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} до "abc", это нормально. Тем не менее, у меня уже есть большое количество записей в другом формате, и я хотел бы продолжать использовать его, так как другие программы тоже зависят от него.

Я думаю, что это должно быть выполнимым, поскольку оно работало без локальных переменных. Кто-нибудь знает, как?

EDIT: Я ошибся. "abc" НЕ работает как вход :(

EDIT 2: я придумал небольшое обходное решение: я конвертирую {a, b, c} → abc, используя

argnew='echo ${arg:1:-1} | tr ',' ' ''

и подача его в программу отлично работает. Это лучшее решение?

Теги:
boost-program-options

1 ответ

0
Лучший ответ

Изменение исходного сценария для добавления -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"
  • 0
    С моей маленькой уловкой преобразования (РЕДАКТИРОВАТЬ 2) мне не нужно переписывать мой ввод данных, и мне не нужно заключать в кавычки все входные переменные. Но я бы не нашел причину без вашей помощи, поэтому я принимаю это как решение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню