2009-05-08 11 views
5

En C, cómo configurar las configuraciones iniciales para algún programa, usando pares clave-valor, con cualquiera o todas: un texto sin formato configuration file, variables de entorno y opciones en la línea de comando. Además, cómo decidir qué valores del método superan a los de los otros dos. Luego, si se han cambiado los valores, para actualizar opcionalmente el archivo de configuración.¿Cómo inicializar un programa C usando archivo, entorno y/o línea de comando?

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

Respuesta

5

Los fundamentos:

  • para configurar su programa usando variables de entorno, puede utilizar la función getenv definido 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 revisar 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 una biblioteca que haga esto por usted en lugar de inventar otro formato de archivo de configuración personalizada. Tenga en cuenta que, dependiendo de la plataforma a la que se dirija, también hay bibliotecas para analizar los argumentos de la línea de comando.

El origen de las configuraciones debe anularse depende de la aplicación, pero en mi opinión generalmente el argumento de línea de comandos> variable de entorno> archivo de configuración tiene más sentido.

Aquí es un ejemplo de conseguir la configuración del medio ambiente y de comandos, con el medio ambiente anulando 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 ves se hace muy largo y tedioso muy pronto, a fin de utilizar mejor una biblioteca existente si existe para ese su (s) plataforma (s) de destino deseada (s), o al menos factorizar 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 puede hacer que su aplicación solo lea y "ejecute" su archivo de configuración, y el usuario puede configurar el archivo de configuración para leer algunas configuraciones del entorno y algunas desde la línea de comando, por ejemplo. Realmente depende del tipo y tamaño de la aplicación y su público objetivo, si vale la pena hacerlo.

+0

Ok, eliminó esa última línea :) – Tobi

2

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

La prioridad entre las configuraciones suele ser tal que las opciones de línea de comando anulan las configuraciones "ambientales". Yo sugeriría prioridades de este tipo, para conciliar el orden de importancia:

  1. opciones de línea de comandos anulan cualquier cosa
  2. archivo
  3. Ajustes está al lado
    • dividir veces entre de usuario local, y el sistema de archivos globales
  4. Vienen las siguientes variables de entorno

Pero el 2 y 3 bien podrían voltearse.

2

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

Hay varias maneras bastante estándar (al menos en el mundo UNIX):

  • variables de entorno
  • archivos de configuración
  • argumentos de la línea
  • comando
  • como un subconjunto de los, archivos de configuración anteriores especificado 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 elecciones, 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 llegar a ser bastante complicado.Si los argumentos de línea de comandos podrían afectar a la interpretación de los archivos de configuración o variable de entorno, pero que todavía quieren la línea de comandos para hacer caso omiso de los otros mecanismos (una buena idea) que puede necesitar tres pases:

  1. analizar la línea de comandos y establecer cualquier variable que afecte a otras configuraciones (digamos qué archivo de configuración leer)
  2. Manejar los archivos de configuración y la variable de entorno (¿en qué orden?)
  3. Vuelva a ejecutar la línea de comando para anular todas las demás configuraciones.

En el aspecto tradición Unix en getopt y getopt_long. Considere también herramientas como gengetopt

Puede simplificar su problema de archivo de configuración convirtiéndolas en scripts de shell que establecen variables de entorno (pero esto lo bloquea en un modelo de 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 debe ahorrar errores y confusión.


Si su entorno de configuración es complicada, es muy útil para encapsular el estado de configuración en una estructura que puede ser pasada alrededor, según sea necesario. Este es el enfoque adoptado por gengetopt, y lo he encontrado útil.

+0

Es más "¿qué mecanismos existen?", Simplemente usando los pares clave-valor usuales para el formato. –

5

Eric Raymond cubre mucho de esto en la Sección 10 de The Art of Unix Programming Obviamente se trata de Unix centrado, pero la mayoría de los principios se pueden aplicar en cualquier sistema operativo.

+1

Sin una imagen de fondo, en http://www.faqs.org/docs/artu/ es más fácil de leer. –

+0

Gracias, Rob. Desearía haberlo encontrado cuando leí todo. :) Actualicé mi enlace. –

1

Para los patrones de diseño de tipo Unix en esta área, un vistazo a Raymond "The Art de UnixProgramming". Discute la priorización de argumentos de línea de comando sobre variables de entorno y archivos de configuración, y así sucesivamente.

1

El lenguaje Lua tuvo su inicio 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 Programación en Lua, una edición anterior de la cual está disponible en línea. Chapter 25 describe el uso de la API Lua C para incrustar Lua como un lenguaje de configuración, y las razones por las que es posible que desee hacer esto.

Cuestiones relacionadas