2

I'm relatively new to C, my question is:

Is it ALWAYS true that there are only EOF chars past the end of a file?

Example code:

FILE *fr;
int i;

fr=fopen("file.txt","r");

for (i=0;i<20;i++) {
    putchar(getc(fr));
}

fclose(fr);

Output:

user@host:~$ ./a.out | xxd
0000000: 6173 640a ffff ffff ffff                 asd.......

(file.txt contains asd\n)

MichalH
  • 1,062
  • 9
  • 20

3 Answers3

8

Answer: there aren't any characters beyond the end of a file. My MSVC manual page here says that if you read past the end of the file, getc() returns EOF.

It does not matter how many times you try to make getc() read past the end of the file, it won't. It just keeps returning EOF.

The EOF is not part of the file marking its end - it is a flag value returned by getc() to tell you there is no more data.

EDIT included a sample to show the behaviour of feof(). Note, I made separate printf() statements, rather than merging them into a single statement, because it is important to be clear what order the functions feof() and getc() are called.

Note that feof() does not return a non-0 value until after getc() returned EOF.

#include <stdio.h>

int main( void )
{
    FILE *fr;
    int i;
    fr=fopen("file.txt","r");
    for (i=0;i<6;i++) {
        printf("feof=%04X, ", feof(fr));
        printf("getc=%04X\n", getc(fr));
    }
    fclose(fr);
}

Program input file:

abc\n

Program output:

feof=0000, getc=0061
feof=0000, getc=0062
feof=0000, getc=0063
feof=0000, getc=000A
feof=0000, getc=FFFFFFFF
feof=0010, getc=FFFFFFFF

So, you can't use feof() to tell you the end of file was reached. It tells that you made a read error after reaching the end of file.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • Although `putchar()` takes an `int` argument, only the lower 8 bits are written out. On my Windows console `0xFF` is a non-printing char, but if I redirect the output to a file I can see the `0xFF` values. – Weather Vane Aug 15 '15 at 17:53
  • Thanks, is it true that a file can contain embedded EOF? I know that I can use feof, but is it the `FF` byte then? – MichalH Aug 15 '15 at 18:14
  • On Windows, you *can* put an embedded EOF character in a **text** file. However, the embedded end-of-file is a ctrl-Z character, decimal 26. On *nix systems, there is no way to embed an EOF in the file itself. – user3386109 Aug 15 '15 at 18:19
  • @Mike of course it can, but `EOF` is an `int` value. It won't be read as `EOF` - each component byte will be read individually as `0xFF`. But also, text files used to contain an end of file marker, such as Ctrl-Z (`0x1A`) but I don't think that's relevant to the question. As for `feof()` - use it at your peril as it is one of the most misunderstood functions in C. – Weather Vane Aug 15 '15 at 18:19
  • @WeatherVane Why? Is it dangerous to use? – MichalH Aug 15 '15 at 18:26
  • @mike you mean `feof()`? Dangerous only when used incorrectly. It does *not* tell you the file pointer is at EOF. It tells you you made a **bad read** beyond the end of the file. http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong You can check it out yourself by printing its value as a second statement in your `for` loop. – Weather Vane Aug 15 '15 at 18:31
  • @user3386109 The ctrl-Z EOF char you mention is, even on Windows, still different from the EOF value returned from eg. `getc()` – Dmitri Aug 15 '15 at 18:43
  • @Dmitri Yes, but if you put a ctrl-Z in a text file on Windows, then `getc` will start returning `EOF` when it reaches that point in the file. – user3386109 Aug 15 '15 at 18:48
  • @mike I expanded my answer to show how `feof()` behaves. – Weather Vane Aug 15 '15 at 18:55
4

There are no EOF characters in a file, nor any characters after the end of a file (it's the end of the file, after all). Rather, EOF is a special value used by getc (and others) to indicate that there isn't anything to read. You can use feof and ferror to see whether that EOF was caused by reaching the end of the file, or if an error ocurred.

What you are seeing are the EOF values (cast to an unsigned char) that getc returned after reaching the end of the file.

Kninnug
  • 7,992
  • 1
  • 30
  • 42
1

Normally, there aren't "EOF chars" in the file to mark the end. EOF is just an integer value, that does not correspond to a valid char value, that is returned by some functions when there's nothing left in the file.

In your example, you see the ff values after the contents of the file because when getc() returns EOF, indicating there's nothing left to read, you're displaying it as a char... effectively displaying the char corresponding to the low bits of the EOF value and ignoring the high bits. If you read the file in a different way, you might not see that result.

Dmitri
  • 9,175
  • 2
  • 27
  • 34