domingo, 15 de marzo de 2015

Ejemplo libconfig con QtCreator: Leer y escribir en el fichero de configuración

En esta entrada veremos un ejemplo de uso de libconfig en linux para trabajar con ficheros de configuración. Usaremos QtCreator como ide.

Lo primero es instalar el paquete libconfig

Desde debian:
apt-get install libconfig

Desde fedora:
yum install libconfig libconfig-devel


Luego debemos linkear la librería desde nuestro IDE. Para ello damos clic derecho al titulo del proyecto y luego en Add Library. Luego colocamos la dirección de el fichero libconfig.so. 
Por lo general está en /usr/lib64/libconfig.so si es un so de 64 bits
Por lo general está en /usr/lib/libconfig.so     si es un so de 32 bits


Puedes hacer el paso anterior de forma manual agregando la siguiente linea a tu fichero .pro
LIBS += -lconfig

Para este ejemplo utilizamos el siguiente fichero de configuración (example.cfg):

// Nombre
nombre = "Libros, Películas y mas";

// Inventario
inventario =
{
  libros = ( { titulo  = "Treasure Island";
              autor = "Robert Louis Stevenson";
              precio  = 29.99;
              qty    = 5; },
            { titulo  = "Snow Crash";
              autor = "Neal Stephenson";
              precio  = 9.99;
              qty    = 8; }
          );

  peliculas = ( { titulo = "Brazil";
               media = "DVD";
               precio = 19.99;
               qty = 11; },
             { titulo = "MEMEMTO";
               media = "VHS";
               precio = 18.99;
               qty = 5; }
           );
};





Este código lee el fichero, muestra su contenido y cambia el valor de la preferencia 'nombre' a Totona.

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


/* Este ejemplo lee el fichero de configuracion example.cfg
 * y muestra su contenido
 */
int main(int argc, char **argv)
{
    static const char *output_file = "updated.cfg";
    static const char *input_file  = "example.cfg";
    config_t cfg;
    config_setting_t *setting;
    const char *str;

    config_init(&cfg);

    /* Lee el fichero, si hay error lo muestra y sale */
    if(! config_read_file(&cfg, input_file))
    {
        fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
                config_error_line(&cfg), config_error_text(&cfg));
        config_destroy(&cfg);
        return(EXIT_FAILURE);
    }    
    

    /* Obtenemos el nombre. */
    if(config_lookup_string(&cfg, "nombre", &str))
        printf("nombre: %s\n\n", str);
    else
        fprintf(stderr, "No hay un campo 'nombre' en example.cfg.\n");

    /* Mostramos todos los libros del inventerio. */
    setting = config_lookup(&cfg, "inventario.libros");
    if(setting != NULL)
    {
        int count = config_setting_length(setting);
        int i;

        printf("%-30s  %-30s   %-6s  %s\n", "titulo", "autor", "precio", "QTY");

        for(i = 0; i < count; ++i)
        {
            config_setting_t *libro = config_setting_get_elem(setting, i);

            const char *titulo, *autor;
            double precio;
            int qty;

            if(!(config_setting_lookup_string(libro, "titulo", &titulo)
                 && config_setting_lookup_string(libro, "autor", &autor)
                 && config_setting_lookup_float(libro, "precio", &precio)
                 && config_setting_lookup_int(libro, "qty", &qty)))
                continue;

            printf("%-30s  %-30s  $%6.2f  %3d\n", titulo, autor, precio, qty);
        }
        putchar('\n');
    }

    /* Muestra todas las peliculas en inventario. */
    setting = config_lookup(&cfg, "inventario.peliculas");
    if(setting != NULL)
    {
        unsigned int count = config_setting_length(setting);
        unsigned int i;

        printf("%-30s  %-10s   %-6s  %s\n", "Titulo", "Media", "Precio", "QTY");
        for(i = 0; i < count; ++i)
        {
            config_setting_t *movie = config_setting_get_elem(setting, i);

            const char *titulo, *media;
            double precio;
            int qty;

            if(!(config_setting_lookup_string(movie, "titulo", &titulo)
                 && config_setting_lookup_string(movie, "media", &media)
                 && config_setting_lookup_float(movie, "precio", &precio)
                 && config_setting_lookup_int(movie, "qty", &qty)))
                continue;

            printf("%-30s  %-10s  $%6.2f  %3d\n", titulo, media, precio, qty);
        }
        putchar('\n');
    }
    
    /** Actualizamos el valor del nombre **/    
    config_setting_t *root,*nombre;

    root = config_root_setting(&cfg);
    nombre=config_setting_get_member(root,"nombre");

    // Cambiamos el valor del nombre y le colocamos
    config_setting_set_string(nombre,"Totona");

    /* Escribimos el fichero de salida*/
    if(! config_write_file(&cfg, output_file))
    {
        fprintf(stderr, "Error escribiendo en el fichero.\n");
        config_destroy(&cfg);
        return(EXIT_FAILURE);
    }

    fprintf(stderr, "Se ha actualizado el fichero %s y se ha guardado en: %s\n",
            input_file,output_file);


    config_destroy(&cfg);
    return(EXIT_SUCCESS);
}



Links de interés:
http://jpmens.net/2009/09/17/reading-configuration-files-with-libconfig/

No hay comentarios:

Publicar un comentario