0

I'm counting the number of lines in a file using feof as you see below. After that finishes, I need to loop line by line through the same file and do another operation that depends on knowing the number of lines. However, while (!feof(f)) won't run a second time on the same file stream. Is there a way to reset the f back to the beginning so I can loop through it again?

 while (!feof(f))
  {
    ch = fgetc(f);
    if(ch == '\n')
    {
      lines++;
    }

  }

  while (!feof(f))
  {
    //need to do an operation that depends on knowing number of lines from first feof but this loop doesn't run because f is at the end

  }
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Leahcim
  • 40,649
  • 59
  • 195
  • 334
  • 4
    Do you know `rewind()` in `stdio`? Also please see [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Weather Vane Mar 17 '17 at 21:41
  • 1
    You can't use `feof()` on file descriptors; `feof()` is for testing file streams, represented by a `FILE *` variable. A file descriptor is a small integer, obtained from `open()` and related functions, and used with `read()`, `write()`, `lseek()`, `close()` etc. Please do not misuse 'descriptor' when you mean 'stream'. – Jonathan Leffler Mar 17 '17 at 21:49

1 Answers1

2

The call you seek is fseek.

Specifically this will set the file position back to the start of the file:

fseek(f, 0, SEEK_SET);

Note that this can fail (for instance if the file isn't a normal file but a socket or some such) so you'd want to check its return value and, if it returns -1, errno.

Benno
  • 5,640
  • 2
  • 26
  • 31
  • [`rewind`](https://msdn.microsoft.com/en-us/library/fes6c2yd.aspx) says *"unlike `fseek`, `rewind` clears the error indicators for the stream as well as the end-of-file indicator"*. – Weather Vane Mar 17 '17 at 21:42
  • You can also use `clearerr` in conjunction with `fseek` to get the same effect with the added bonus that you'll get clear error reporting. `rewind` would require you to zero out `errno` first. – Benno Mar 17 '17 at 21:45
  • @Benno: nothing in the standard C or POSIX libraries ever sets `errno` to zero. The end-of-file indicator and the error indicator for a file stream are separate from `errno` — almost wholly unrelated to it. – Jonathan Leffler Mar 17 '17 at 21:53
  • I meant that your program would have to explicitly set `errno` to zero before calling `rewind` if you intended to properly error check. Quoting the FreeBSD man page: `Since rewind() does not return a value, an application wishing to detect errors should clear errno, then call rewind(), and if errno is non-zero, assume an error has occurred.` – Benno Mar 17 '17 at 22:50