11

Quali pacchetti si utilizzano per gestire le opzioni della riga di comando, le impostazioni e i file di configurazione?Come gestite le opzioni della riga di comando e i file di configurazione?

Sto cercando qualcosa che legge opzioni definite dall'utente dalla riga di comando e/o dai file di configurazione.

Le opzioni (impostazioni) devono essere divisibili in diversi gruppi, in modo da poter passare diverse (sottoinsiemi di) opzioni a diversi oggetti nel mio codice.

Conosco boost::program_options, ma non riesco ad abituarmi allo API. Esistono alternative leggere?

(BTW, usi mai un oggetto opzioni globali nel codice che può essere letto da qualsiasi luogo, oppure puoi prendere in considerazione che il male?)

risposta

5

Beh, Non mi piacerà la mia risposta. Io uso boost::program_options. L'interfaccia richiede un po 'di tempo per abituarsi, ma una volta che ce l'hai, è incredibile. Assicurati di effettuare il caricamento in barca dei test unitari, perché se ottieni la sintassi errata, il tuo avrà errori di runtime.

E, sì, li memorizzo in un oggetto singleton (sola lettura). Non penso che sia male in quel caso. È uno dei pochi casi a cui riesco a pensare dove sia accettabile un singleton.

+1

+1 per boost :: program_options, ma solo giusto! Farei attenzione nell'usare le opzioni del programma come un singleton. Siamo stati morsi da questo in quanto ora dobbiamo aggiungere diversi set di opzioni per diversi file. Per prima cosa è necessario tornare indietro e rimuovere il singleton in modo da poter memorizzare i diversi set di opzioni per ogni singolo file. –

+0

Buon punto, Richard. Io uso boost :: program_options per un gioco, e ovviamente 1 set di opzioni è sufficiente per processo, ma per scopi diversi questa sarebbe una cattiva idea. – rlbond

+0

Sei ancora favorevole a boost :: program_options? Sembra non essere più sviluppato (il sito web di docs è stato modificato l'ultima volta nel 2004). Fa uso/è compatibile con C++ 11? Quando leggi tra le righe del tuo post, in realtà non è affatto una buona raccomandazione: * Assicurati solo di fare dei boatload di test delle unità, perché se ottieni la sintassi sbagliata otterrai errori di runtime * è una grande bandiera rossa! – Walter

-4

Prova Apache Ant. Il suo utilizzo principale è rappresentato dai progetti Java, ma non contiene nulla di Java e può essere utilizzato praticamente per qualsiasi cosa.

L'utilizzo è abbastanza semplice e hai anche un sacco di supporto per la community. È davvero bravo a fare le cose nel modo in cui lo chiedi.

Per quanto riguarda le opzioni globali nel codice, penso che siano abbastanza necessarie e utili. Non abusare di loro, però.

+3

Uuh, Apache Ant? Lo strumento di costruzione? Che cosa ha a che fare con la lettura delle opzioni della riga di comando in C++? – Frank

+0

Si può conservare un file di configurazione di base per il C++, ma tutto il lavoro effettivo può essere fatto con Ant. Vedi http://www.codemesh.com/products/junction/doc/ant_cpp.html o semplicemente http://www.google.com/search?hl=it&site=&q=using+ant+c%2B%2B&btnG= Cerca –

0

Non sono sicuro dell'argomentazione dell'argomento della riga di comando. Non ho avuto bisogno di funzionalità molto ricche in quell'area e generalmente ho fatto il mio per salvare ulteriori dipendenze dal mio software. A seconda di quali sono le tue esigenze potresti provare o meno questa rotta. I programmi C++ che ho scritto non sono generalmente richiamati dalla riga di comando.

D'altra parte, per un file di configurazione non si può battere un formato basato su XML. È leggibile, estendibile, strutturato, ecc ... :) Inoltre ci sono molti parser XML là fuori. Nonostante sia una libreria C, tendo ad usare libxml2 da xmlsoft.org.

+0

Controlla [pugixml.org] (http://pugixml.org) per un veloce parser XML scritto in C++. Come bonus, supporta 'XPath' ed è anche solo l'intestazione! – Sean

3

Se Boost è eccessivo per te, è probabilmente anche lo GNU Gengetopt, ma IMHO, è uno strumento divertente con cui gironzolare.

E, cerco di stare lontano dagli oggetti delle opzioni globali, preferisco che ogni classe legga la propria configurazione. Oltre a tutta la filosofia "Globali sono cattivi", tende a diventare un disastro sempre crescente per avere tutta la tua configurazione in un unico posto, ed è anche più difficile dire quali variabili di configurazione vengono utilizzate dove. Se si mantiene la configurazione più vicina al punto in cui viene utilizzata, è più ovvio per cosa ciascuno è destinato e più facile da mantenere pulito.

(come quello che uso per, personalmente, per tutto quello che di recente è stato un proprietario biblioteca riga di comando di analisi che qualcun altro alla mia azienda ha scritto, ma che non ti aiuta molto, purtroppo)

1

GNU getopt è molto carino. Se vuoi un tocco C++, considera getoptpp che è un wrapper attorno al getopt nativo. Per quanto riguarda il file di configurazione, dovresti cercare di renderlo il più stupido possibile in modo che l'analisi sia facile. Se sei un po 'premuroso, potresti voler usare yaac & lex, ma sarebbe davvero un grosso problema per le piccole app.

Vorrei anche suggerire di supportare sia i file di configurazione che le opzioni della riga di comando nell'applicazione. I file di configurazione sono migliori per quelle opzioni che devono essere cambiate meno frequentemente. Le opzioni della riga di comando sono buone quando vuoi passare gli argomenti che cambiano immediatamente (in genere quando crei un'applicazione, che verrebbe chiamata da qualche altro programma.)

11

In Google, utilizziamo gflags. Non fa i file di configurazione, ma per i flag, è molto meno doloroso dell'uso di getopt.

#include <gflags/gflags.h> 
DEFINE_string(server, "foo", "What server to connect to"); 
int main(int argc, char* argv[]) { 
    google::ParseCommandLineFlags(&argc, &argv, true); 
    if (!server.empty()) { 
     Connect(server); 
    } 
} 

si mette la DEFINE_foo nella parte superiore del file che ha bisogno di conoscere il valore della bandiera. Se anche altri file devono conoscere il valore, utilizzare DECLARE_foo in essi. C'è anche un buon supporto per i test, quindi i test di unità possono impostare diversi flag in modo indipendente.

+0

Mi piace! Sembra molto facile da usare. – Milan

1

Se si sta lavorando con Visual Studio 2005 su Windows x86 e x64, alcune utilità di analisi della riga di comando sono disponibili in SimpleLibPlus library. L'ho usato e l'ho trovato molto utile.

3

Sto usando TCLAP per un anno o due ora, ma casualmente ci siamo imbattuti in ezOptionParser. ezOptionParser non soffre di "non dovrebbe essere questo complesso" - sindrome come lo fanno gli altri analizzatori di opzioni.

Sono abbastanza impressionato finora e probabilmente lo userò in futuro, in particolare perché supporta i file di configurazione. TCLAP è una libreria più sofisticata, ma la semplicità e le funzionalità extra di ezOptionParser sono molto interessanti.

Altri vantaggi dal suo sito includono (al 0.2.0):

  • Abbastanza stampa di ingressi analizzate per il debug.
  • Creazione di messaggi di utilizzo automatico in tre layout (allineati, interlacciati o sfalsati).
  • Implementazione di file di intestazione singola.
  • dipendente solo da STL.
  • Nome di opzione arbitrario breve e lungo (trattini '-' o più '+' prefissi non richiesti).
  • Delimitatori di elenchi di argomenti arbitrari.
  • Istanze di flag multiple consentite.
  • Convalida delle opzioni richieste, numero di argomenti previsti per flag, intervalli di tipi di dati, intervalli definiti dall'utente, appartenenza a liste e caso per elenchi di stringhe.
  • Criteri di convalida definibili da stringhe o costanti.
  • Importazione di più file con commenti.
  • Esporta su file, imposta le opzioni o tutte le opzioni, inclusi i valori predefiniti quando disponibili.
  • Indice di analisi delle opzioni per i contesti dipendenti dall'ordine.
+0

So che questo è un thread molto vecchio, ma solo per evitare che qualcun altro cada nella stessa trappola come ho fatto io, dopo aver letto questo thread. ezOptionParser funziona bene per le opzioni di analisi, ma ha un bug fatale che blocca l'applicazione se si utilizza la funzione getUsage() per segnalare le opzioni della riga di comando. La libreria non è supportata dall'autore ora, quindi questo bug non verrà mai corretto. Usare con estrema cautela; o meglio, usa qualcos'altro. – Graham