Square
Square

Reputation: 149

How can I know text file is empty or not?(in C)

I'm trying to detect text file is empty or not in C. (values are initialized in NULL) Whenever read first in value(using fscanf), it always returns file has zero, even if it has value "0" or "empty".

How can I know the target text file is empty or not? (it should be distinguished even it has "0" in first letter)

Upvotes: 1

Views: 1730

Answers (3)

Rocoder
Rocoder

Reputation: 1103

you can do using ftell

#include <stdio.h>

int get_file_size (char *filename) {
   FILE *fp;
   int len;

   fp = fopen(filename, "r");
   if( fp == NULL )  {
      perror ("Error opening file");
      return(-1);
   }
   fseek(fp, 0, SEEK_END);

   len = ftell(fp);
   fclose(fp);

   return(len);
}

Upvotes: 1

chqrlie
chqrlie

Reputation: 145317

If the file was successfully open for read, as per fopen(filename, "r"), you can verify if it is empty before any read operation this way:

int is_empty_file(FILE *fp) {
    int c = getc(fp);
    if (c == EOF)
        return 1;
    ungetc(c, fp);
    return 0;
}

ungetc() is guaranteed to work for at least one character. The above function will return 1 if the file is empty or if it cannot be read, due to an I/O error. You can tell which by testing ferr(fp) or feof(fp).

If the file is a stream associated to a device or a terminal, the test code will block until at least one byte can be read, or end of file is signaled.

If the file is a regular file, you could also use a system specific API to determine the file size, such as stat, lstat, fstat (on Posix systems).

Upvotes: 2

Enzo Ferber
Enzo Ferber

Reputation: 3104

If you're under Linux, you can use stat or fstat:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);

Will give you this information:

struct stat {
    dev_t     st_dev;     /* ID of device containing file */
    ino_t     st_ino;     /* inode number */
    mode_t    st_mode;    /* protection */
    nlink_t   st_nlink;   /* number of hard links */
    uid_t     st_uid;     /* user ID of owner */
    gid_t     st_gid;     /* group ID of owner */
    dev_t     st_rdev;    /* device ID (if special file) */
    off_t     st_size;    /* total size, in bytes */
    blksize_t st_blksize; /* blocksize for file system I/O */
    blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
    time_t    st_atime;   /* time of last access */
    time_t    st_mtime;   /* time of last modification */
    time_t    st_ctime;   /* time of last status change */
};

To check for the size using stat:

struct stat info;

if(stat(filepath, &info) < 0) {
    /* error */
}

if(info.st_size == 0) { 
    /* file is empty */
}

Or using fstat:

int fd = open(filepath, O_RDONLY);
struct stat info;

if(fstat(fd, &info) < 0) {
    /* error */
}

if(info.st_size == 0) { 
    /* file is empty */
}

Upvotes: 1

Related Questions