Domanda

In C, come configurare le impostazioni iniziali per alcuni programmi, usando coppie chiave-valore, con uno o tutti: un semplice testo file di configurazione , variabili di ambiente e opzioni sulla riga di comando. Inoltre, come decidere quali valori del metodo hanno la precedenza su quelli degli altri due. Quindi, se i valori sono stati modificati, per aggiornare facoltativamente il file di configurazione.

Qual è il modo più semplice per farlo, e quali sono i metodi più accettati? Esiste un programma open source, preferibilmente di piccole dimensioni, che fornisce un buon esempio di come farlo?

È stato utile?

Soluzione

Le basi:

  • Per configurare il programma usando le variabili di ambiente, è possibile utilizzare la funzione getenv definita in stdlib.h.
  • Per configurare il tuo programma usando gli argomenti della riga di comando, dichiara la tua funzione principale come 'int main (int argc, const char * const * argv)', e usa un ciclo per andare oltre gli argomenti nell'array argv. La sua dimensione è data da argc.
  • Per configurare il tuo programma usando un file di configurazione, scegli preferibilmente una libreria facendo questo per te invece di inventare un altro formato di file di configurazione personalizzato. Si noti che a seconda della piattaforma scelta come destinazione, esistono anche librerie per analizzare gli argomenti della riga di comando.

Le origini delle impostazioni che devono sovrascrivere a vicenda dipendono dall'applicazione, ma a mio avviso in genere argomento da riga di comando > variabile d'ambiente > il file di configurazione ha più senso.

Ecco un esempio di come ottenere la configurazione dall'ambiente e dalla riga di comando, con l'ambiente di comando a riga di comando:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, const char* const* argv) {
    int i;
    const char* myConfigVar;

    // get default setting from environment
    myConfigVar = getenv("MY_CONFIG_VAR");

    // if the variable wasn't defined, initialize to hardcoded default
    if (!myConfigVar)
        myConfigVar = "default value";

    // parse commandline arguments
    // start at 1, because argv[0] contains the name of the program
    for (i = 1; i < argc; ++i) {
        if (strcmp("--my-config-var", argv[i]) == 0) {
            if (i + 1 < argc)
                myConfigVar = argv[i + 1];
            else
                printf("missing value for my-config-var argument\n");
        }
    }

    printf("myConfigVar = '%s'\n", myConfigVar);
    return 0;
}

Si vede già che diventa molto lungo e noioso molto presto, quindi è meglio usare una libreria esistente se ne esiste una per le piattaforme di destinazione desiderate, o almeno considerare questo tipo di codice in un numero di funzioni.

Un'altra opzione interessante è quella di associare un linguaggio di scripting alla tua applicazione, quindi puoi fare in modo che l'applicazione legga e "esegua" solo il tuo file di impostazioni e l'utente potrebbe configurare il file di impostazioni per leggere alcune impostazioni dall'ambiente e alcune dalla riga di comando, ad esempio. Dipende molto dal tipo e dalle dimensioni dell'applicazione e dal tuo pubblico di destinazione se vale la pena farlo.

Altri suggerimenti

Eric Raymond tratta molto di questo nella Sezione 10 di L'arte della programmazione Unix Ovviamente questo è incentrato su Unix, ma la maggior parte dei principi può essere applicata in qualsiasi sistema operativo.

Esistono tonnellate di librerie per gestire l'analisi dei file di configurazione, per vari formati. Cerca i formati XML e INI, per due scelte popolari. Scrivere un parser personalizzato è probabilmente una cattiva idea, dal momento che può essere un sacco di lavoro per un guadagno scarso o nullo. Qui c'è una libreria C casuale per l'analisi dei file INI, XML viene lasciato come esercizio.

La priorità tra le impostazioni è in genere tale che le opzioni della riga di comando hanno la precedenza su qualsiasi "ambientale" impostazioni. Vorrei suggerire priorità come questa, in ordine decrescente di importanza:

  1. Le opzioni della riga di comando hanno la precedenza su qualsiasi cosa
  2. Il file delle impostazioni è successivo
    • Talvolta suddiviso tra file locali dell'utente e file globali di sistema
  3. Next come variabili di ambiente

Ma i 2 e 3 potrebbero essere capovolti.

La domanda non è tremendamente chiara. È la domanda "quali meccanismi esistono?", "Quali sono le convenzioni per argomenti e formati?" O "come dovrei mescolare e abbinare"? "

Esistono diversi modi piuttosto standard (almeno nel mondo unix):

  • variabili di ambiente
  • file di configurazione
  • argomenti della riga di comando
  • come sottoinsieme di quanto sopra, file di configurazione specificati nella riga di comando

Per scegliere quali metodi usare per il tuo programma, esamina molti dal canone della pratica accettata prima di congelare le tue scelte, leggere alcuni blog, leggere alcuni libri ...

I file di configurazione sono probabilmente i più portatili tra i sistemi operativi.

Il trattamento può diventare abbastanza complicato. Se gli argomenti della riga di comando potrebbero influire sull'interpretazione dei file di configurazione o della variabile di ambiente, ma si desidera comunque che la riga di comando prevalga sugli altri meccanismi (una buona idea), potrebbero essere necessari tre passaggi:

  1. Analizza la riga di comando e imposta tutte le variabili che influenzano ulteriori impostazioni (indica quale file di configurazione leggere)
  2. Gestisci i file di configurazione e la variabile d'ambiente (quale ordine?)
  3. Riesegui la riga di comando per sovrascrivere tutte le altre impostazioni.

Nella tradizione unix, guarda getopt e getopt_long . Considera anche strumenti come gengetopt

Puoi semplificare il problema del file di configurazione rendendoli script di shell che impostano le variabili di ambiente (ma questo ti blocca in un modello unix). L'analisi del testo semplice è semplice e multipiattaforma, ma rende più codice da scrivere. L'uso di un formato standard e di una libreria impone requisiti per l'ambiente di costruzione dell'utente, ma dovrebbe risparmiare su bug e confusione.


Se l'ambiente di configurazione è complicato, è molto utile incapsulare lo stato di configurazione in una struttura che può essere passata in base alle esigenze. Questo è l'approccio adottato da gengetopt e l'ho trovato utile.

Per i modelli di design simili a Unix in quest'area, guarda Raymond's " The Art di Unix Programmazione " ;. Discute la definizione delle priorità degli argomenti della riga di comando rispetto alle variabili di ambiente e ai file di configurazione e così via.

La lingua Lua è stata in parte motivata dalla necessità di avere un linguaggio di configurazione ben definito per una raccolta di strumenti. Resta abbastanza facile integrare Lua come linguaggio di configurazione. Un esempio abbastanza completo è nel libro Programmazione in Lua, una vecchia edizione della quale è disponibile online. Capitolo 25 descrive l'utilizzo dell'API Lua C per incorporare Lua come linguaggio di configurazione e motivi perché potresti voler fare questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top