【问题标题】:File empty check文件空检查
【发布时间】:2020-05-31 06:52:22
【问题描述】:

我做了一个函数来检查文本文件是否为空。我使用 fseek 和 ftell 进行检查,但问题是如果第一行是 '\n' 并且下一行是 EOF 那么 ftell 将返回 2 而不是 0 。我想检查文件是否真的为空,但我想不出是否有办法检查上述情况。请帮忙 。这是我的代码

void fileReader(FILE *file,char filePath[]){
char output[100];
file = fopen(filePath,"r");
printf("Content of file : ");
fseek(file, 0, SEEK_END); 
printf("%d",ftell(file));
if(ftell(file)==0){
    printf("\nthere is nothing here");
}
else{  
    do{
        printf("%s", output);  
    }while (fscanf(file, "%s", output) != EOF);
} 
fclose(file);
}

【问题讨论】:

  • 在您描述的情况下,ftell() 应该返回 1,而不是 0。无论如何,问题是您如何定义“空”。带有\n 的文件是空的吗?一百万个换行符呢?空格和换行符呢?如果您愿意接受内容为“空”的文件,则需要读取文件的内容并将其与您的空内容标准进行匹配。
  • 您在代码中使用"%d" 转换说明符调用Undefined Behavior 以打印long int。类型和转换说明符之间的任何不匹配都会引发未定义的行为。它应该是"%ld" 来伴随额外的 4 个字节。见C11 Standard - 7.21.6.1 The fprintf function(p9)
  • 是的,我认为文件只包含空格、制表符、换行符等是空的,但我不知道如何检查它
  • @bruno 是的,谢谢,我现在明白了

标签: c


【解决方案1】:

但问题是如果第一行是 '\n' 而下一行是 EOF,那么 ftell 将返回 2 而不是 0

您不想知道文件是否为空,即其大小为 0,但如果文件包含其他内容,例如空格、制表符、换行符等,在这种情况下,大小是不够的。一种方法可以是:

#include <stdio.h>

int main(int argc, char ** argv)
{
  FILE * fp;

  if (argc != 2)
    fprintf(stderr, "Usage %s <file>\n", *argv);
  else if ((fp = fopen(argv[1], "r")) == NULL)
    perror("cannot read file");
  else {
    char c;

    switch (fscanf(fp, " %c", &c)) { /* note the space before % */
    case EOF:
      puts("empty or only spaces");
      break;
    case 1:
      puts("non empty");
      break;
    default:
      perror("cannot read file");
      break;
    }
    fclose(fp);
  }

  return 0;
}

fscanf(fp, " %c", &amp;c)% 之前的空格要求绕过空格(空格、制表符、换行符...)

编译和执行:

pi@raspberrypi:/tmp $ gcc -Wall c.c
pi@raspberrypi:/tmp $ ./a.out /dev/null
empty or only spaces
pi@raspberrypi:/tmp $ echo > e
pi@raspberrypi:/tmp $ wc -c e
1 e
pi@raspberrypi:/tmp $ ./a.out e
empty or only spaces
pi@raspberrypi:/tmp $ echo "   " > e
pi@raspberrypi:/tmp $ echo "   " >> e
pi@raspberrypi:/tmp $ wc -c e
8 e
pi@raspberrypi:/tmp $ ./a.out e
empty or only spaces
pi@raspberrypi:/tmp $ echo "a" >> e
pi@raspberrypi:/tmp $ cat e


a
pi@raspberrypi:/tmp $ ./a.out e
non empty
pi@raspberrypi:/tmp $ 
pi@raspberrypi:/tmp $ chmod -r e
pi@raspberrypi:/tmp $ ./a.out e
cannot read file: Permission denied
pi@raspberrypi:/tmp $ ./a.out
Usage ./a.out <file>
pi@raspberrypi:/tmp $ 

【讨论】:

  • @DavidC.Rankin 不,我使用的格式不是"%c",而是" %c"% 之前的空格会改变所有要求fscanf 绕过“空格”
  • 明白了...这更有意义。 (我该更新眼镜了……)
  • @DavidC.Rankin 在某种程度上当"%s" 有一个隐含空间并且scanf 家庭确实喜欢" %s"
  • 是的,这就是为什么"%s" 是我的第一个想法,但" %c" 会做同样的事情。 (你不能对空间视而不见:)
猜你喜欢
  • 2015-07-02
  • 2013-03-31
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 2019-04-24
  • 2011-05-03
  • 1970-01-01
相关资源
最近更新 更多