2017-09-06 3 views
1

Le code suivant détecte les arguments spécifiés plusieurs fois. L'analyseur d'arguments de ligne de commande est implémenté pour s'assurer que l'utilisateur fournit un string (mps-file), un integer (n) et un sequence of integer (0, n-1) permettant aux autres d'être optionnels.booster les options du programme: argument étant détecté plus d'une fois

Toutefois, lorsque le code est compilé en utilisant les drapeaux suivants:
g++ -std=c++11 test.cpp /home/not_me/my_lib/boost_1_64_0/stage/lib/libboost_program_options.so

qui compile parfaitement. Mais lorsqu'il est exécuté de la manière suivante, il lève l'exception suivante.

/src/a.out --mps-file earth.mps --n 5 --size 10 --seed 10 --order 0 1 2 3 4 
error: option '--mps-file' cannot be specified more than once 

Mais si elle est exécutée en utilisant la commande suivante, il fonctionne très bien:
./src/a.out earth.mps 5 10 10 --order 0 1 2 3 4

code complet:

#include <iostream> 
#include <numeric> 

#include <boost/program_options.hpp> 

int main (int argc, char* argv[]) { 

    int n; 
    int sample_size = 10; 
    std::random_device rd; 
    int seed = rd(); 
    std::string mps_name; 
    std::vector<int> order; 

    boost::program_options::options_description desc("options"); 
    desc.add_options() 
     ("mps-file", boost::program_options::value<std::string>(&mps_name)->required(), "input mps file") 
     ("n", boost::program_options::value<int>(&n)->required(), "number of variables") 
     ("size", boost::program_options::value<int>(&sample_size)->default_value(sample_size), "size of sample") 
     ("seed", boost::program_options::value<int>(&seed)->default_value(seed), "seed value") 
     ("order", boost::program_options::value<std::vector<int>>(&order)->required(), "ordering") 
     ("help", "this help message") 
     ; 

    boost::program_options::positional_options_description p; 
    p.add("mps-file", 1); 
    p.add("n", 1); 
    p.add("order", -1); 

    boost::program_options::variables_map vm; 

    try { 
     boost::program_options::store(boost::program_options::command_line_parser(argc, argv). 
             options(desc).positional(p).run(), vm); 

     if (vm.count("help") || argc == 1) { 
      std::cout << "usage: " << argv[0] << " [options]" << std::endl; 
      std::cout << desc; 
      return -1; 
     } 

     boost::program_options::notify(vm); 
    } 
    catch (std::exception& e) { 
     std::cout << "error: " << e.what() << std::endl; 
     return -1; 
    } 

    std::vector<int> temp = order; 
    std::sort(temp.begin(), temp.end()); 
    for (int i = 0; i < n; ++i) { 
     if (temp[i] == i) { continue; } 
     std::cout << "incorrect ordering given" << std::endl; 
     return -1; 
    } 

    if (n != order.size()) { 
     std::cout << "mismatch between the 'n' and given ordering" << std::endl; 
     return -1; 
    } 

    return 0; 
} // main 
+0

@MarkB J'ai aussi essayé. Se débarrasser des arguments positionnels (en commentant 'p.add()') et le problème persiste toujours. – letsBeePolite

+0

'libboost_program_options.s'? Les fichiers .s sont assembleur de code source - il me semble très bizarre que vous ayez assemblé le fichier 'gcc' ... –

+0

@MarkB arguments positionnels _require_ la description de l'option nommée doit exister dans les options du programme Boost – sehe

Répondre

0

Le problème est avec les options de position. Lorsque vous les supprimez et l'appel positional(p) de boost::program_options::command_line_parser(argc, argv). options(desc).positional(p).run() votre problème sera parti. Comme vous avez seulement supprimé les lignes add() et laissé positional(p), vous avez un problème différent: "trop ​​d'options de position ont été spécifiées sur la ligne de commande".

Je suppose que le problème avec votre appel:

/src/a.out --mps-file earth.mps --n 5 --size 10 --seed 10 --order 0 1 2 3 4

est que quand il y a une option de position définie sur la position 1, peut alors être considérée comme la chaîne ---mps-file une valeur de cette option elle-même. Donc, vous devriez probablement éviter de passer des options avec des noms, si les options ont été définies comme positionnelles.

+0

Cela n'a pas fonctionné pour moi – letsBeePolite

+0

@letsBeePolite Qu'est-ce qui n'a pas fonctionné pour vous? Quel genre d'erreur vous obtenez quand vous quittez simplement: '' 'boost :: program_options :: command_line_parser (argc, argv) .options (desc) .run()' '' '? –