Reputation: 149
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
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
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
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