-1

What's the best way to check if I've reached the end of a FILE* stream without manually keeping track of the current cursor position and file size? The implementation should work in read and read/write mode of fopen.

I came up with this:

int iseof(FILE *fp)
{
    int ch = fgetc(fp);
    if(ch == EOF) return 1;
    ungetc(ch, fp);
    return 0;
}

This does the trick but of course it has the overhead of reading a character and potentially pushing it back into the stream. That's why I was wondering whether there was a nicer solution. Just using feof() won't work because this will only return true if reading at or past the end of file has occurred.

Any ideas?

Andreas
  • 9,245
  • 9
  • 49
  • 97
  • In C, we typically just do this check manually in a while loop. – Code-Apprentice Jan 15 '17 at 16:58
  • It's probably easier to understand if you integrate this check into the call site and do use `feof` or equivalent *after* the attempted operation. – Kerrek SB Jan 15 '17 at 16:58
  • 3
    This don't make sense, seem like a XY problem. – Stargateur Jan 15 '17 at 17:00
  • _"What's the best way to check if I've reached the end of a FILE* "_ best way for **what**? – edmz Jan 15 '17 at 17:02
  • Why do you think you need to know that there is nothing after the data you just read? It usually isn't necessary — the next time you read, you find you're at EOF and proceed onwards to do whatever EOF processing is necessary. – Jonathan Leffler Jan 15 '17 at 17:03
  • "This does the trick" --> not well. Note that `int iseof(FILE *fp)` is a false positive when a file error caused the `EOF` return. – chux - Reinstate Monica Jan 15 '17 at 17:04
  • @chux: Good spot, thanks. I'll fix that. – Andreas Jan 15 '17 at 17:37
  • Idea: "current cursor position and file size" --> an input stream need not have a "position" or "size". OTOH, if code _knows_ the position of the end-of-file, just use `int iseof(FILE *fp) { return ftell(fp) == eof_position; }` IOWs no need to keep track of "current cursor position **and** file size", just "file size" as "current cursor position" is readily found with `tell()`. – chux - Reinstate Monica Jan 15 '17 at 17:58
  • @chux: This would probably be nicer but keeping track of the file size is not trivial in my case because lots of code is involved and it also needs to work when the file is in read/write mode with potential overwriting involved. – Andreas Jan 15 '17 at 18:16
  • @Andreas Such additional requirements belong in the post. It is a problem of coming up with an answer that meets OP's posted requirements only to later find new ones, that leads to a dance of commentary. Perhaps if you have a candidate working function and test code to show it, look at [code review](http://codereview.stackexchange.com) for critical analysis.and request for improvements like [this](http://stackoverflow.com/questions/41663730/check-if-the-next-read-will-set-eof-indicator?noredirect=1#comment70525799_41663730) – chux - Reinstate Monica Jan 15 '17 at 18:22
  • Well, I thought it was rather obvious that if the requirement was no keeping track of cursor position and size that I didn't want a solution that just used `ftell()` instead of tracking the cursor. I mean `ftell()` is rather stdio primary school so I thought it was obvious that this wasn't what I wanted. But sorry that I didn't make myself clearer. Still, your solution is probably the only clean way because stdio probably really doesn't provide a way to do what I want. So if I don't want to use the hackish solution from above, tracking the size is probably really the only clean way. – Andreas Jan 15 '17 at 21:00

1 Answers1

0

It is probably best to just do this check manually in a while loop than try to write a function to wrap it up:

ch = fgetc(fp);
while (ch != EOF) {]
  // do something with ch
  ch = fgetc(fp);
}
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • Thanks, but this isn't what I'm looking for. I'm really looking for a function that checks whether the cursor is currently at the end of the file. – Andreas Jan 15 '17 at 17:36
  • @Andreas C has no such function. This is the way to do it. – Code-Apprentice Jan 15 '17 at 17:38
  • Ok, then I need to go with my approach as presented above. All other solutions proposed here are to no avail because my use case is rather unusual. I'm developing a new backend for a toolkit interface that specifically needs me to implement a function which says whether or not a `FILE*` stream is currently at the end of the stream. – Andreas Jan 15 '17 at 17:41
  • @Andreas This is exactly what `feof()` does. You should really add in your question your use case because what you do is a very bad practice. And your solution is very slow. – Stargateur Jan 15 '17 at 17:43
  • 1
    No, `feof()` only returns true *after* an attempt to read at or past the end of file has been made. It doesn't return true when the cursor is at the end of file and no attempts to read from it have been made so far. But that's what I need. I need it to return true even if no attempts to read from the end of file have been made yet. Hence my function. I mentioned that this is the reason why I can't use `feof()` in the original posting. – Andreas Jan 15 '17 at 17:46
  • @Andreas I think you misunderstanding EOF. Whenever you read a character successfully, you are **not** at eof yet. You only reach eof when a read fails. – Code-Apprentice Jan 15 '17 at 17:49
  • @Andreas You wrong, you miss understanding cursor and EOF. There is no value EOF, it's a state. The cursor can't be at the EOF because there is no EOF in a file. It's a state. – Stargateur Jan 15 '17 at 17:49
  • Agreed, but does it really matter here? I don't see how. I still need a function that can tell whether the next read will set the EOF state ;) – Andreas Jan 15 '17 at 18:15
  • @Andreas How will this function be used? – Code-Apprentice Jan 15 '17 at 18:20