2

I have a basic question about file pointers. In the code below i have a while loop followed by a for loop. The for loop only will show the line count unless i fopen the file again - is that normal? and if so should i fclose it after the while loop beforehand? There's probably some "rewind" function that i'm unaware of, so my whole approach might be wrong. I realize both the while loop and for can be combined, but this my question is about the fopen, fclose and using the data again from fopen.

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

#define MAXLEN 200

enum { MAXLINES = 200 };
char lpath[MAXLINES][BUFSIZ];

int main(int argc, char **argv) {

        char c;
        int l = 0, n = 0, i = 0, count = 0;
        char lines[MAXLINES][BUFSIZ];

        FILE *fp = fopen(argv[1], "r");

        if (fp == 0) {
                fprintf(stderr, "failed to open input.txt\n");
                exit(1);
        }

        while (l < MAXLINES && fgets(lines[l], sizeof(lines[0]), fp)) {
                lines[l][strlen(lines[l])-1] = '\0';
                puts(lines[l]);
                l++;
        }

        // fp = fopen(argv[1], "r"); // below won't output unless fopen again
        for (c = getc(fp); c != EOF; c = getc(fp)) {
            if (c == '\n') { 
                count++;

        }
        printf(">> line count: %i", count);

        fclose(fp);
}

looked also at: Pointer best practice

Community
  • 1
  • 1

2 Answers2

5

It's normal, you need to rewind() the file. The problem is that when the for loop start the file has reached the end, so reads will fail and feof() will return non-zero.

Two options

rewind(fp);

Or

fseek(fp, 0L, SEEK_SET);

When you call fopen() again you leak resources because you overwrite the pointer and now you can't fclose() the first fopen()ed file.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
0

You could use rewind() as @iharob suggested, or you could just close and re-open the file:

while (l < MAXLINES && fgets(lines[l], sizeof(lines[0]), fp)) {
            lines[l][strlen(lines[l])-1] = '\0';
            puts(lines[l]);
            l++;
}

fclose(fp);
fp = fopen(argv[1], "r"); // below won't output unless fopen again
for (c = getc(fp); c != EOF; c = getc(fp)) {
    if (c == '\n') { 
        count++;
    }
}
SevenBits
  • 2,836
  • 1
  • 20
  • 33