2016-11-23 4 views
0

Я пытаюсь обнаружить, что текстовый файл пуст или нет в C. (значения инициализируются в NULL) Всякий раз, когда сначала считывается значение (используя fscanf), он всегда возвращает файл с нулевым значением, , даже если он имеет значение «0» или «пустое».Как я могу узнать, что текстовый файл пуст или нет? (В C)

Как узнать, что целевой текстовый файл пуст или нет? (следует отличать даже имеет "0" в первом письме)

+1

Должно быть EOF, не так ли? –

+1

Проверьте, не равен ли размер файла нулю? –

+4

Кроме того, это помогло бы, если бы вы могли рассказать нам, что вы на самом деле делаете *! Предпочтительно, создавая [Минимальный, Полный и Подтверждаемый пример] (http://stackoverflow.com/help/mcve). Также укажите фактическое содержимое файла, если оно есть. И, наконец, пожалуйста, [прочитайте о том, как задавать хорошие вопросы] (http://stackoverflow.com/help/how-to-ask), если вы еще этого не сделали. –

ответ

1

Если файл был успешно открыт для чтения, в соответствии с fopen(filename, "r"), вы можете проверить, если он пуст, прежде чем какой-либо операции чтения таким образом:

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

ungetc() гарантированно работайте хотя бы на одного персонажа. Вышеуказанная функция вернет 1, если файл пуст или если его невозможно прочитать из-за ошибки ввода-вывода. Вы можете определить, какие из них можно проверить: ferr(fp) или feof(fp).

Если файл представляет собой поток, связанный с устройством или терминалом, тестовый код будет блокироваться, пока не будет прочитан хотя бы один байт, или будет сигнализирован конец файла.

Если файл является обычным файлом, вы можете также использовать определенную систему API для определения размера файла, например stat, lstat, fstat (на системах Posix).

+0

Это работает как шарм. спасибо – Square

0

Если вы под Linux, вы можете использовать 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); 

Даст вам эту информацию:

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 */ 
}; 

Чтобы проверить размер с помощью stat:

struct stat info; 

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

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

Или с помощью fstat:

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

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

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

вы можете сделать с помощью 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); 
} 
+0

3 проблемы: 'ftell()' может не возвращать размер файла в текстовых потоках, он может не работать в потоках, где поиск не поддерживается, например, терминал, и он может возвращать '0', если тип' int' слишком мал для фактического размера файла, например, если файл имеет ровно 4 ГБ. – chqrlie

+0

@chqrlie yes, У этого есть ограничения. но он все еще удовлетворяет ответ, поскольку искатель хотел знать, что файл имеет некоторые данные или нет. Не предполагали эти случаи. Спасибо за указание. – Rocoder

Смежные вопросы