Pregunta

En C, cómo configurar los ajustes iniciales para algún programa, usando pares clave-valor, con cualquiera o todos: un texto plano archivo de configuración , variables de entorno y opciones en la línea de comando. Además, cómo decidir qué valores del método anulan los de cualquiera de los otros dos. Luego, si se han cambiado los valores, para actualizar opcionalmente el archivo de configuración.

¿Cuál es la forma más sencilla de hacer esto y cuáles son los métodos más aceptados? ¿Existe un programa de código abierto, preferiblemente pequeño, que dé un buen ejemplo de cómo se puede hacer esto?

¿Fue útil?

Solución

Lo básico:

  • Para configurar su programa usando variables de entorno, puede usar la función getenv definida en stdlib.h.
  • Para configurar su programa usando argumentos de línea de comando, declare su función principal como 'int main (int argc, const char * const * argv)', y use un bucle para repasar los argumentos en la matriz argv. Su tamaño viene dado por argc.
  • Para configurar su programa utilizando un archivo de configuración, preferiblemente elija alguna biblioteca que lo haga por usted en lugar de inventar otro formato de archivo de configuración personalizado. Tenga en cuenta que, según la plataforma a la que se dirija, también hay bibliotecas para analizar los argumentos de la línea de comandos.

La fuente de configuración que debe anularse entre sí depende de la aplicación, pero en mi opinión, en general, el argumento de línea de comando variable de entorno > el archivo de configuración tiene más sentido.

Aquí hay un ejemplo de cómo obtener la configuración del entorno y la línea de comandos, con el entorno de anulación de la línea de comandos:

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

Ya ve que se vuelve muy largo y tedioso muy pronto, así que mejor use una biblioteca existente si existe para la plataforma o plataformas de destino deseadas, o al menos tenga en cuenta este tipo de código en una serie de funciones.

Otra opción interesante es vincular un lenguaje de scripting a su aplicación, luego podría hacer que su aplicación solo lea y ejecute " su archivo de configuración, y el usuario podría configurar el archivo de configuración para leer algunas configuraciones del entorno y algunas de la línea de comandos, por ejemplo. Realmente depende del tipo y tamaño de la aplicación y su público objetivo si vale la pena hacerlo.

Otros consejos

Eric Raymond cubre mucho de esto en la Sección 10 de El arte de la programación en Unix Obviamente, esto está centrado en Unix, pero la mayoría de los principios se pueden aplicar en cualquier sistema operativo.

Hay toneladas de bibliotecas para tratar el análisis de archivos de configuración, para varios formatos. Busque formatos XML e INI, para dos opciones populares. Escribir un analizador personalizado es probablemente una mala idea, ya que puede ser mucho trabajo con poco o ningún beneficio. Aquí es una biblioteca C aleatoria para analizar archivos INI, XML se deja como ejercicio.

La prioridad entre las configuraciones suele ser tal que las opciones de la línea de comando anulan cualquier "ambiental" ajustes Sugeriría prioridades como esta, en orden descendente de importancia:

  1. Las opciones de línea de comando anulan cualquier cosa
  2. El archivo de configuración es el siguiente
    • A veces se divide entre los archivos locales del usuario y los archivos globales del sistema
  3. Luego vienen las variables de entorno

Pero los 2 y 3 bien podrían invertirse.

La pregunta no es terriblemente clara. ¿Es la pregunta "qué mecanismos existen?", "¿Cuáles son las convenciones para los argumentos y los formatos?" O "¿cómo debo mezclar y combinar?"

Hay varias formas bastante estándar (al menos en el mundo de Unix):

  • variables de entorno
  • archivos de configuración
  • argumentos de línea de comando
  • como un subconjunto de los archivos de configuración anteriores especificados en la línea de comando

Para elegir qué métodos usar para su propio programa, examine muchos programas del canon de práctica aceptada antes de congelar sus propias opciones, leer algunos blogs, leer algunos libros ...

Los archivos de configuración son probablemente los más portátiles en todos los sistemas operativos.

El tratamiento puede ser bastante complicado. Si los argumentos de la línea de comando pueden afectar la interpretación de los archivos de configuración o la variable de entorno, pero aún así desea que la línea de comando anule los otros mecanismos (una buena idea), puede necesitar tres pases:

  1. Analiza la línea de comando y establece cualquier variable que afecte la configuración adicional (di qué archivo de configuración leer)
  2. Manejar archivos de configuración y variables de entorno (¿en qué orden?)
  3. Vuelva a ejecutar la línea de comando para anular todas las demás configuraciones.

En la tradición de Unix, mire getopt y getopt_long . Considere también herramientas como gengetopt

Puede simplificar su problema de archivo de configuración convirtiéndolos en scripts de shell que establecen variables de entorno (pero esto lo encierra en un modelo unix). Analizar texto plano es fácil y multiplataforma, pero genera más código para escribir. El uso de un formato estándar y una biblioteca impone requisitos al entorno de compilación de su usuario, pero debería ahorrar errores y confusión.


Si su entorno de configuración es complicado, es muy útil encapsular el estado de configuración en una estructura que se pueda transmitir según sea necesario. Este es el enfoque adoptado por gengetopt , y he encontrado que es útil.

Para patrones de diseño tipo Unix en esta área, mire Raymond's " The Art de Unix Programación " ;. Discute la priorización de los argumentos de la línea de comandos sobre las variables de entorno y los archivos de configuración, etc.

El idioma Lua comenzó en parte motivado por la necesidad de tener un lenguaje de configuración bien definido para Una colección de herramientas. Sigue siendo bastante fácil integrar Lua como lenguaje de configuración. Un ejemplo bastante completo se encuentra en el libro Programming in Lua, una edición anterior de la cual está disponible en línea. El Capítulo 25 describe el uso de la API de Lua C para incrustar Lua como lenguaje de configuración, y los motivos por qué querrías hacer esto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top