Reputation: 515
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
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