How to use boost program_options to read an integer array?

你。 提交于 2019-12-12 01:56:00

问题


I am using Ubuntu and boost v1.50.

Previously I used boost program_options to feed a set of options into a program like so:

#!/bin/bash

./prog --arg1 1 --arg2 "2" --arg3 {1,2,3} --arg4 {1,2} --arg5 5

So I am dealing with a mix of single integers, strings and integer arrays. This worked fine.

However, after "improving" the code by introducing local variables in bash, I have:

#!/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

Executing this results in an error:

error: the argument ('{1,2,3}') for option '--arg3' is invalid

I have set up the boost program_options like this:

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;
}

Where did I go wrong? Is multitoken not appropriate in this context? What can I use instead? Is it not possible to read integer arrays?

I tried omitting multitoken but then it fails also. Using quotation marks around the local variable in the bash script does not help either.

If I change the array input from {a,b,c} to "a b c", it is ok. However, I already have a large number of entries in the other format and I am would like to continue using it as other programs depend on it too.

I think it should be doable, since it worked without the local variables. Does someone know how?

EDIT: I have been mistaken. "a b c" does NOT work as input :(

EDIT 2: I came up with a little workaround: I convert {a,b,c} -> a b c using

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

and the feeding it to the program works fine. Is that the best solution?


回答1:


Changing your original script to add the -x bash debugging option, like this:

#!/bin/bash -x

./prog --arg1 1 --arg2 "2" --arg3 {1,2,3} --arg4 {1,2} --arg5 5

and then running it shows this output:

+ ./prog --arg1 1 --arg2 2 --arg3 1 2 3 --arg4 1 2 --arg5 5

So your curly brace groupings aren't working they way you think they're working, because bash command line processing is expanding them before invoking ./prog.

You can get it working if in your second script, if you change the assignments for a3 and a4 to be like this:

a3='1 2 3'
a4='1 2'

and then double-quote all your variables when you call ./prog:

./prog --arg1 "$a1" --arg2 "$a2" --arg3 "$a3" --arg4 "$a4" --arg5 "$a5"


来源:https://stackoverflow.com/questions/27891139/how-to-use-boost-program-options-to-read-an-integer-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!