【问题标题】:How can I know text file is empty or not?(in C)我怎么知道文本文件是否为空?(在 C 中)
【发布时间】:2016-11-23 12:00:13
【问题描述】:

我正在尝试检测 C 中的文本文件是否为空。 (值在 NULL 中初始化) 每当首先读取值时(使用 fscanf),它总是返回文件为零, 即使它的值为“0”或“空”。

我如何知道目标文本文件是否为空? (即使首字母有“0”也要区分)

【问题讨论】:

  • 应该是EOF吧?
  • 检查文件大小是否为零?
  • 另外,如果您能告诉我们您实际在做什么,那将会很有帮助!最好创建一个Minimal, Complete, and Verifiable Example。还包括文件的实际内容(如果有)。最后请read about how to ask good questions如果你还没有这样做。
  • 一个文本文件包含 C 中的 整数 字符。NULL 是一个带有 null pointer 常量的宏。 => 文本文件不能包含NULL!
  • @ChandanaKumara:提示:C 不是 C++。

标签: c file-io


【解决方案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() 保证至少对一个字符有效。如果文件为空或由于 I/O 错误而无法读取,上述函数将返回 1。您可以通过测试 ferr(fp)feof(fp) 来判断哪个。

如果文件是与设备或终端关联的流,则测试代码将阻塞,直到可以读取至少一个字节,或发出文件结束信号。

如果文件是常规文件,您还可以使用系统特定的 API 来确定文件大小,例如 statlstatfstat(在 Posix 系统上)。

【讨论】:

    【解决方案2】:

    如果你在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 */
    }
    

    【讨论】:

      【解决方案3】:

      你可以使用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);
      }
      

      【讨论】:

      • 3 个问题:ftell() 可能不会在文本流上返回文件大小,它可能会在不支持搜索的流(例如终端)上失败,如果输入 @987654325,它可能会返回 0 @ 对于实际文件大小来说太小了,例如,如果文件正好是 4GB。
      • @chqrlie 是的,它有局限性。但它仍然满足答案,因为提问者想知道文件是否有一些数据。没有假设这些情况。感谢您指出。
      猜你喜欢
      • 2012-09-21
      • 1970-01-01
      • 2021-06-10
      • 2014-09-28
      • 2012-10-15
      • 2019-10-17
      • 1970-01-01
      • 2014-11-09
      • 2012-08-29
      相关资源
      最近更新 更多