2013-03-20 7 views
11
//Using boost program options to read command line and config file data 
    #include <boost/program_options.hpp> 
    using namespace std; 
    using namespace boost; 
    namespace po = boost::program_options; 

int main (int argc, char *argv[]) 
{ 
    po::options_description config("Configuration"); 
    config.add_options() 
       ("IPAddress,i","IP Address") 
       ("Port,p","Port") 
       ; 

    po::variables_map vm; 
    po::store(po::parse_command_line(argc, argv, config),vm); 
    po::notify(vm); 

    cout << "Values\n"; 

    string address = (vm["IPAddress"].as<std::string >()).c_str(); 
    string port = (vm["Port"].as<std::string>()).c_str(); 

    cout << (vm["IPAddress"].as<string>()).c_str(); 
    cout << " " << (vm["Port"].as<string>()).c_str(); 

    return 0; 

} 

Sind die eingegebenen Werte irgendwie nicht druckbar?Wie löse ich "boost :: bad_any_cast: fehlgeschlagene Konvertierung mit boost :: any_cast", wenn Boost-Programmoptionen verwendet werden?

Hier ist gdb Ausgang scheint Problem geworfen werden werden:

nach dem Werfen einer Instanz genannt terminate 'boost :: exception_detail :: clone_impl

' was(): boost :: bad_any_cast: failed Umwandlung boost :: any_cast

 Program received signal SIGABRT, Aborted. 
     0x0000003afd835935 in raise() from /lib64/libc.so.6 
string address = (vm["IPAddress"].as<std::string >()).c_str(); 

ist, wo der Fehler auftritt; Ich habe std :: string und string mit den gleichen Ergebnissen versucht.

testboostpo -i 192.168.1.10 -p 5000 

ist die Befehlszeile.

habe ich versucht, die Arten zu erklären, wie so:

config.add_options() 
     ("IPAddress,i", po::value<std::string>(), "IP Address") 
      ("Port,p", po::value<std::string>(), "Port"); 

aber der Fehler aufgetreten ist nach wie vor.

Könnte das ein echter Fehler sein?

+0

Bitte schreiben Sie die Befehlszeilenargumente, die Sie an das Programm übergeben. – Praetorian

+0

nit: es ist überflüssig, das Ergebnis von 'std :: string :: c_str()' in ein 'std :: string' zu konvertieren –

Antwort

13

Sie sehen die boost::bad_any_cast vom po::variables_map geworfen Ausnahme, weil die beiden const char* Argument Überlastung von po::options_description_easy_init::operator() kein spezifiziert po::value_semantic Typ, so dass es in eine std::string konvertiert wird nicht funktionieren. Wenn Sie den Wert in einen std::string konvertieren möchten und dies für Ihre Anwendung erforderlich ist, verwenden Sie die Wertemantik required().

Beachten Sie den hinzugefügten Catch-Block seit dem Parsen kann (und wird, wie Sie bemerkt haben) Ausnahmen werfen. Hier ist eine Beispielsitzung:

samm$ ./a.out 
the option '--IPAddress' is required but missing 
samm$ ./a.out --IPAddress 127.0.0.1 
the option '--Port' is required but missing 
samm$ ./a.out --IPAddress 127.0.0.1 --Port 5000 
Values 
address: 127.0.0.1 
port: 5000 
samm$ 

Hier ist ein online demo das gleiche Verhalten zeigt, mit freundlicher Genehmigung von Compile-Verbindungsdurchlauf (coliru).

4

Sie müssen die IP-Adresse und Port als Strings erklären, wenn Sie die Optionen hinzu:

config.add_options() 
    ("IPAddress,i", po::value<std::string>(), "IP Address") 
    ("Port,p", po::value<std::string>(), "Port") 
    ; 
+0

teilweise korrekt, eine' boost :: bad_any_cast' Ausnahme [wird noch geworfen] (http : //coliru.stacked-crooked.com/view? id = f50049b76d804061b926500aa6953033-57c67fe4b82106f02cd504259a9a9be3) wenn eine Option, die nicht in der 'po :: variables_map' enthalten ist, in eine' std :: string' umgewandelt wird. –

2

Die gleiche Meldung kann auch auftreten, wenn Sie optionale Argumente nicht korrekt behandeln.

Sams Lösung Nägel benötigt Argumente und der OP-Code schlägt vor - nur markieren Sie sie erforderlich. Für die optionalen Eingänge, gibt the Boost PO tutorial uns eine Vorlage zur Überprüfung, ob die Möglichkeit besteht, bevor es Umwandlung:

if(vm.count("address")) 
{ 
    const std::string address = vm["IPAddress"].as<std::string>(); 
    std::cout << "address: " << address << std::endl; 
} 
if(vm.count("port")) 
    const std::string port = vm["Port"].as<std::string>(); 
    std::cout << "port: " << port << std::endl; 
} 

Mein Problem - ich hatte kopiert/eingefügt und vergessen, die, wenn der Test mit der Nutzung auszurichten!

Verwandte Themen