2
int main(int argc, char *argv[])
{
    int c = EOF;
    FILE *fp = fopen("./temp.txt", "r");
    assert(fp!=NULL);
    while (1) {
        c = fgetc(fp);
        if (EOF != c) {
            putchar(c);
        }
    }

    return 0;
}

temp.txt is a slowly increasing log file, so this program can read the EOF. After it first encounters EOF, I thought it should stop getting new added data of temp.txt, while it just acts like tail -f temp.txt and continues printing new lines of the file.

Yes, I know there is an infinite loop. The problem is that I thought, when fgetc first encounters EOF, it should do some recording in the struct fp, and the next callings of fgetc should check this and return EOF immediately. Why it continues to read the data on the disks, didn't it reach the end-of-file? Is this the expected behavior?

William Pursell
  • 204,365
  • 48
  • 270
  • 300
Grove
  • 21
  • 2
  • better to write: `while ((c = fgetc(fp)) != EFO){ putchar(c);} ` – Grijesh Chauhan Jul 26 '13 at 13:03
  • 1
    You're apparently linking your program against Glibc. Had you linked it against uClibc, it would have crashed on first call to fgetc after EOF. Reading from a FILE after EOF is unspecified. – andyn Jul 26 '13 at 13:07
  • Be aware that the proper way of knowing that your are at the end of the file is to use the `feof` function as describe in the man page. – mathk Jul 26 '13 at 13:18
  • Many implementations do as you expect. However, not all do. The behavior of `fgetc` after it has returned `EOF` for a stream is unspecified. – William Pursell Jul 27 '13 at 04:52

5 Answers5

2

Quick answer is, there is no break that exits the while loop.

When it reads EOF, it loops back around and holds on c = fgetc(fp);.

If you need it to stop reading when it hits the EOF you can add an else:

while (1) {
    c = fgetc(fp);
    if (EOF != c) {
        putchar(c);
    } else {
        // reached the EOF
        break;
    }
}
newfurniturey
  • 37,556
  • 9
  • 94
  • 102
1

You aren't telling it to leave the while loop when finding an EOF though, you are only saying if you do find a EOF don't do anything with it. You would need to put a conditional break from the loop or have a condition until which the while loop will continue.

Jon Taylor
  • 7,865
  • 5
  • 30
  • 55
0
int main(int argc, char *argv[])
{
    int c = EOF;
    FILE *fp = fopen("./temp.txt", "r");
    assert(fp!=NULL);
    while (1) { // here
        c = fgetc(fp);
        if (EOF != c) {
            putchar(c);
        }
    }

    return 0;
}

It's because you have an infinite loop which can't be stopped (except with some signals). This program will read temp.txt for the eternity.

nouney
  • 4,363
  • 19
  • 31
0
int main(int argc, char *argv[])
{
    int c = EOF;
    FILE *fp = fopen("./temp.txt", "r");
    assert(fp!=NULL);
    while (1) {
        c = fgetc(fp);
        if (EOF != c) {
            putchar(c);
        }
        else
          break; //this will fix your problem of infinite loop even finding EOF
    }

    return 0;
}
pradipta
  • 1,718
  • 2
  • 13
  • 24
0

IMO it would be nicer looking when you do

int c = 0;
while ((c = fgetc(fp)) != EOF)
{
    putchar(c);
}
Serve Laurijssen
  • 9,266
  • 5
  • 45
  • 98