Fichero de configuracion II

by

La última vez dejé un problema sin resolver, que era la dificultad de parsear con scanf después de haber guardado el último dato que necesitas. La solución no es una solución general, es un simple truco para comprobar que después sólo haya espacios. El código es este:

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

#define SPACES " \n\t\r\v"
#define COMMENT '#'

int main()
{
    FILE* file;

    file = fopen("meshias.cfg", "r");

    if(!file)
    {
        perror("File couldn't not be opened");
        return -1;
    }

    char key[64], value[256];
    char line[512];

    int bytes = 0;
    int n_line = 0;
    char *pos = NULL;

    while(fgets(line, 511, file))
    {
        n_line++;
        printf("%d: ", n_line);

        // Eliminar el comentario
        if (pos = strchr(line, COMMENT))
        {
            *pos = '\0';
            printf("Hay un comentario. ");
        }

        if (strlen(line) == 0)
        {
            puts("Linea vacia.");
        }
        else if (strlen(line) == 1 && strncmp(line, "\n", 1) == 0)
        {
            puts("Linea vacia.");
        }
        else if (sscanf(line, " %63s = %255s%n", key, value, &bytes) == 2)
        {
            if (strspn(&line[bytes], SPACES) == strlen(&line[bytes]))
            {
                printf("Clave: %s, Valor: %s\n", key, value);
            }
            else
            {
                puts("Linea incorrecta.");
            }
        }
        else if (strspn(line, SPACES) == strlen(line))
        {
            puts("Linea con espacios.");
        }
        else
        {
            puts("Linea incorrecta.");
        }
    }

    if(!feof(file))
    {
        perror("Error leyendo el fichero");
        return -1;
    }

    puts("El programa acabo satisfactoriamente.");

    fclose(file);

    return 0;
}

La primera diferencia es que tenemos un define donde definimos lo que queremos que aceptar como caracteres validos en una línea, en nuestro caso los ya mencionados espacios, tabulaciones y saltos de líneas. Si nos vamos a la línea 57, donde se comprueba si una línea está compuesta por SPACES, ha cambiado. Ahora se usa la función strspn. Esta función devuelve, empezando desde el principio, el número de caracteres consecutivos de la primera cadena compuestos por los caracteres de la segunda. Al comprobar que esa función devuelva el tamaño de la línea, estamos comprobando realmente que toda la línea esté compuesta por los caracteres SPACES. De está manera conseguimos suplir las carencias de scanf.

El otro caso era un poco más complejo. Necesitabamos saber si después de capturar el par clave valor, el resto de caracteres también fueran SPACES. Como vemos en la línea 46 capturamos con scanf el par, y además, el número de bytes leídos. ¿Y para qué lo hacemos? Muy sencillo. Luego comprobamos que la cadena a partir del último byte leído, también sea un conjunto de caracteres SPACES; de la misma manera que lo hicimos en el anterior caso.

Bueno y después de este pequeño truco ya podemos integrar esto en el código. Sólo hace falta comprobar un poco que ocurriría cuando se sobrepasa los buffer, pero por ahora voy a intentar centrarme en adelantar un poco el proyecto.

Advertisement

Deja un comentario

Fill in your details below or click an icon to log in:

Logo de WordPress.com

You are commenting using your WordPress.com account. Log Out / Cambiar )

Twitter picture

You are commenting using your Twitter account. Log Out / Cambiar )

Facebook photo

You are commenting using your Facebook account. Log Out / Cambiar )

Connecting to %s


Seguir

Get every new post delivered to your Inbox.