J Szum
J Szum

Reputation: 515

Reading Part of a File in C

I have a file that contain few different sections. All sections have a start section and end section lines to distinguish between sections.

How can I read lines from section-2?

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

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

With my current code, all the file is printed (all sections except words separating sections). I understand the issue is that in my fgets I'm reading the file until #end Section-2 and I probably need another while loop to read lines from specific start section. But I'm not sure how can I change the code so it will only output words inside the section-2.

Expected output:

Other
words
are
also
here.

What I get now:

Some
words 
are 
here.
Other 
words 
are 
also
here. 

My code:

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

Upvotes: 0

Views: 70

Answers (1)

David C. Rankin
David C. Rankin

Reputation: 84561

You are thinking along the correct lines. The key is to set a flag when you find the first "Section-X" to read and then while that flag is set, tokenize each line until the closing "Section-X" is found, at which time you exit your read-loop.

You can check for "Section-X" however you like, using the entire line, or just the "Section-X" identifier (which I chose below). To locate the "Section-X" text, just use strrchr() to find the last space in each line, and compare from the next character to the end of line for your section, e.g.

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

Example Use/Output

With your input stored in the file dat/sections.txt and reading default "Section-2":

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

Reading "Section-1":

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

Look things over and let me know if you have questions.

Upvotes: 1

Related Questions