Tengo un archivo que contiene algunas secciones diferentes. Todas las secciones tienen una sección de inicio y líneas de sección final para distinguir entre secciones.

¿Cómo puedo leer las líneas de la sección 2?

>start Section-1
    Some words are here.
>end Section-1

>start Section-2
    Other words are also here.
>end Section-2

Con mi código actual, se imprime todo el archivo (todas las secciones excepto las palabras que separan las secciones). Entiendo que el problema es que en mi fgets estoy leyendo el archivo hasta #end Section-2 y probablemente necesito otro bucle while para leer las líneas de la sección de inicio específica. Pero no estoy seguro de cómo puedo cambiar el código, por lo que solo generará palabras dentro de la sección-2.

Salida esperada:

Other
words
are
also
here.

Lo que obtengo ahora:

Some
words 
are 
here.
Other 
words 
are 
also
here. 

Mi código:

#define MAXSTR 1000
#define END ">end Section-2\n"
#define ENDWORD ">end"
#define STRWORD ">start"
#define SECTION "Section-2"

int main () {

    FILE *file; 
    char lines[MAXSTR];
    char delim[2] = " ";
    char *words;

    if ((file = fopen("sample.txt", "r")) == NULL) {
        printf("File empty.\n");
        return 0;
    }

    while (strcmp(fgets(lines, MAXSTR, file), END) != 0) { 

        words = strtok(lines, delim);

        while (words != NULL && strcmp(words, STRWORD) != 0 
                             && strcmp(words, SECTION) != 0 
                             && strcmp(words, ENDWORD) != 0) {

            printf("%s\n", words);
            words = strtok(NULL, delim);
        }
    }
    fclose(fileUrl);
    return 0; 
}
c
0
D Szum 22 ene. 2021 a las 12:23

1 respuesta

La mejor respuesta

Estás pensando en las líneas correctas. La clave es establecer un indicador cuando encuentre el primer "Section-X" para leer y luego, mientras ese indicador está configurado, tokenizar cada línea hasta que se encuentre el "Section-X" de cierre, momento en el que saldrá de su ciclo de lectura. .

Puedes buscar "Section-X" como quieras, usando la línea completa, o solo el identificador "Section-X" (que elegí a continuación). Para ubicar el texto "Section-X", simplemente use strrchr() para encontrar el último espacio en cada línea y compare desde el siguiente carácter hasta el final de la línea de su sección, p. Ej.

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

#define MAXC 1024

int main (int argc, char **argv) {
    
    if (argc < 2) { /* validate 1 arg givent for filename */
        fprintf (stderr, "usage: %s file [\"Section-X\" (default: 2)]\n", argv[0]);
        return 1; 
    }
    
    const char *section = argc > 2 ? argv[2] : "Section-2",     /* set section */
        *delim = " ";
    char line[MAXC];
    int found = 0;                      /* found flag, 0-false, 1-true */
    FILE *fp = fopen (argv[1], "r");    /* open file */
    
    if (!fp) {  /* validate file open for reading */
        perror ("fopen-fp");
        return 1;
    }
    
    while (fgets (line, MAXC, fp)) {                /* read each line */
        line[strcspn (line, "\n")] = 0;             /* trim \n from end */
        char *p = strrchr(line, ' ');               /* pointer to last space */
        if (p && strcmp (p + 1, section) == 0) {    /* compare "Section-X" */
            if (found++)                            /* check/set found flag */
                break;                              /* break loop if 2nd "Section-X" */
            continue;
        }
        if (found) {    /* if found set, tokenize each line */
            for (p = strtok (line, delim); p; p = strtok (NULL, delim))
                puts (p);
        }
    }
}

Ejemplo de uso / salida

Con su entrada almacenada en el archivo dat/sections.txt y lectura predeterminada "Section-2":

$ ./bin/read_sections dat/sections.txt
Other
words
are
also
here.

Leyendo "Section-1":

$ ./bin/read_sections dat/sections.txt "Section-1"
Some
words
are
here.

Revisa las cosas y avísame si tienes preguntas.

1
David C. Rankin 22 ene. 2021 a las 10:03