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

int main(void) {

    FILE *fp;

    fp = fopen("clients.dat", "wb");
    fclose(fp);

    fp = fopen("clients.dat", "rb");

    while (1) {
        if (fp == EOF)
            break;
        else 
            printf("There is something inside a file");
    }

    fclose(fp);
    return 0;
}

Here comes a question: what do empty binary files contain? should the pointer point to the EOF character? I mean: isn't it that the first and last thing in the file is EOF? OR how Can I check whether a file is empty or not?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • . Please see the [ask] help page and [The perfect question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/) blog post by Jon Skeet. – Sourav Ghosh Oct 07 '20 at 07:22
  • Please ___properly___ indent your code. Machine (Compiler) can read and compile anything, but for humans, it needs to make a little _sense_ while reading a block of text as _code_. Take a moment to read through the [editing help](//stackoverflow.com/editing-help) in the help center. Formatting on Stack Overflow is different than on other sites. The better your post looks, the easier it is for others to read and understand it. – Sourav Ghosh Oct 07 '20 at 07:22
  • See https://stackoverflow.com/questions/12389518/representing-eof-in-c-code – Support Ukraine Oct 07 '20 at 07:24
  • I'm not sure that the above link real represents a dupe but it does tell you that EOF is **not** a character. In other words - an empty file doesn't contain EOF – Support Ukraine Oct 07 '20 at 07:28
  • ok if then what empty binary file contains how can i check for its emptyness? – Will Hunting Oct 07 '20 at 07:30
  • Also notice that `fp` will never ever be EOF. The value EOF is a value that can be returned when doing some operation on `fp` – Support Ukraine Oct 07 '20 at 07:31
  • Do you mean that an empty file doesnt have any special character or constant that determines the end of a file ? – Will Hunting Oct 07 '20 at 07:38
  • 1
    `EOF` is not a character, it's a **signal**. Pretty much like if you ask your friend "How old are you?" and she sends the signal "Go to hell!" the signal is not an age. So you ask your system what character is is the file (`getchar()` or similar) and the system sends you a signal that there is no character or that there's an error. – pmg Oct 07 '20 at 08:03
  • Files can have size of 0 bytes. They cannot contain an `EOF` indicator as file content. In C `EOF` is of type `int` anyway which has different size on different architectures. – Gerhardh Oct 07 '20 at 08:18

4 Answers4

2

An empty file contains nothing, it is empty. So it contains 0 bytes. EOF is not a character that is at the end of a file, it is an integer constant used as return value from some of the standard methods reading from a file to indicate end of file or some sort of error.

When you open a file you get a pointer to a FILE type back, this is what you can expect even from an empty file.

A file is not terminated the same way a string is, so there is no equivalent of a NULL character in a file, that determines when the file contents stops.

To determine whether a file you have opened and have a valid FILE pointer to is empty you can use fseek and ftell:

fseek(fp, 0, SEEK_END);
size = ftell(fp);
if (size == 0) {
    // File is empty
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Tommy Andersen
  • 7,165
  • 1
  • 31
  • 50
1

Function fopen returns a pointer to a file handle of type FILE, not a pointer to any content of the file or a pointer to an EOF-character. The pointer is NULL if the file could not be opened at all, but does not indicate whether the file is empty or not.

To check if a file is empty you either (1) need to make an attempt to read bytes and handle the various results, or (2) to use fseek and ftell to move the read pointer to the end and ask then for the position.

(1)

fp=fopen("clients.dat","rb");
char buffer;
size_t bytesRead = fread(&buffer, 1, 1, fp); // try to read one byte
if(bytesRead == 1) {
    printf("file contains at least one byte\n");
} else { // error handling
   if (feof(fp))
      printf("Attemt to read though end of file has been reached. File is empty.\n");
   else if (ferror(fp)) {
       perror("Error reading file.");
   }
}

(2)

fp=fopen("clients.dat","rb");
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
if (size==0) {
   // file is empty.
}

I'd prefer the second variant.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • The second variant might identify some interactive devices as empty files. Yet it would be perverse to name such a device `clients.dat` :) – chqrlie Oct 07 '20 at 08:53
  • Note that you need specific system guarantees for `fseek()`/`ftell()` to work. Per the C standard, `fseek()` to the end of a binary file is specifically identified as undefined behavior, and `ftell()` on a text file is not defined as a byte offset - it's only defined to return a value that can be used by `fseek()` to return to the same location in the file. Since system-specific features are needed to get the size of a file, you might as well use them directly. Even Windows supports `fileno()` and `fstat()`, so `fstat( fileno( fp ), &statbuf )` gets the file size directly fairly portably. – Andrew Henle Oct 07 '20 at 09:04
1

Here comes a question what empty binary files contain ?

Empty files contain nothing, that is what makes them empty.

Regular files have a size which is not part of their data, but instead is normally a part of the directory entry or inode.

should the pointer point to the EOF character ?

No

First of all the pointer returned by fopen is NOT a pointer to the content of the file, but merely a pointer to a data structure describing the open file.

Secondly EOF is not an actual part of the file, but a special return value from the getc family of functions used to indicate that the end of file has been reached.

To test whether you are at the end of a file without reading from it you can use the feof function.

plugwash
  • 9,724
  • 2
  • 38
  • 51
1

Here's another approach:

To check if the file is empty, you can simply read the file:

int c = fgetc(fp);
if (c == EOF)
{
    // The file is empty or an error occured
    if (feof(fp))
    {
        // Empty
    }
    else
    {
        // Error during file read
    }
}
else
{
    // non-empty file
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • Then it means i should read at least one character and check with feof function. Can not i check directyly with feof fucntion without reading a character ? – Will Hunting Oct 07 '20 at 07:46
  • @WillHunting No, you can't use `feof` without doing a read first. It's the read that sets the EOF status that `feof` returns. – Support Ukraine Oct 07 '20 at 08:26