【问题标题】:fclose() always returns EOFfclose() 总是返回 EOF
【发布时间】:2012-08-04 03:47:03
【问题描述】:

我有一个函数可以从文件中读取特定格式的整数。 它可以按需要正常工作,但是每当我尝试使用 fclose() 关闭文件时, fclose() 总是返回 EOF。

有什么建议吗?我是学生,还在学习。 我把代码放在下面。如果您需要“处理”代码,请告诉我。谢谢:)

// Open the file
FILE *myFile = fopen(fileName, "r");
if(myFile == NULL){
    //Handle error
    fprintf(stderr, "Error opening file for read \n");
    exit(1);
}

while(myFile != EOF)
{
     // read and process the file
     // this part works.
}

// always returns EOF here. WHY?
if (fclose(myFile) == EOF) {
    // Handle the error!
    fprintf(stderr, "Error closing input file.\n");
    exit(1);
}
printf("Done reading the file.");

编辑: 谢谢大家的回复。抱歉,我无法发布代码,因为这是我作业的一部分。我试图获得一些帮助,我并不是要你们为我编写代码。根据我的教授的说法,发布代码是非法的(因为其他学生可以看到并可能复制,这就是他告诉我的)。我只能在周日之后发布代码。现在,我将尝试修改我的代码并避免使用 fscanf。谢谢,我很抱歉。

【问题讨论】:

  • 这个:while (myFile != EOF) 是错误的。 myFile 是一个指针; EOF 的类型为 int。比较它们几乎肯定会产生一个编译器诊断,你绝对不应该忽略它——而且很可能会导致无限循环。这让我觉得while (myFile != EOF) 并不是真的在你的代码中。请给我们看真实的代码。
  • @keithThompson 在我的代码中,它可以正常工作,很奇怪。但是我刚刚将其更改为 while(!feof(myFile)) (在看到您的评论后)。谢谢
  • @KeithThompson 实际上是问题所在!该代码可以正常工作。您可以将您的评论发布为帖子,以便我将其标记为答案吗?谢谢

标签: c eof fclose


【解决方案1】:

这个:

while(myFile != EOF)

实际上是非法的(违反约束)。任何符合标准的 C 编译器都需要发出诊断;默认情况下,gcc 仅发出警告(确实有资格作为“诊断”)。

如果 gcc 给了你一个警告,你应该注意它; gcc 经常发出警告,恕我直言,应该将其视为致命错误。如果它没有给你一个警告,你可能会用禁用警告的选项来调用它(这很奇怪,因为它默认会产生那个警告)。 -Wall -Wextra -std=c99 -pedantic 是一组不错的选择(或调整 -std=... 选项以强制执行不同版本的标准)。

myFile 是指针类型,特别是FILE*EOF 的类型为 int,通常扩展为 (-1)。您不能合法地将指针值与整数值进行比较(空指针常量的特殊情况除外,但这不适用于此处。)

假设程序没有被拒绝,我预计这会导致无限循环,因为myFile 几乎肯定不会等于EOF

可以改成

while (!feof(myFile))

但这可能会导致其他问题。从文件读取时检测文件结尾的正确方法是使用您正在使用的任何函数返回的值来读取数据。请查阅您正在使用的函数的文档,以查看它在遇到文件结尾或错误条件时返回的内容。 feof() 函数可用于确定,您完成阅读之后,您是否遇到文件结束或错误情况。

【讨论】:

  • @dsutandi:阅读您调用的任何函数的文档都会很有帮助。
【解决方案2】:

由于您无法对以只读模式打开的常规文件执行任何操作,这会导致 fclose 出错,因此您很可能在未显示的代码中存在错误在myFile 结构上。

另外,测试 myFile != EOF 永远不会为真,因为您将其设置为 fopen 的返回,它永远不会给您 EOF 并且您已经检查了 NULL 您的意思是不是这样:

while((c = fgetc(myFile)) != EOF) {
    // do stuff
}

【讨论】:

  • 在我没有显示的代码中,我使用 fscanf 来读取每个整数。我在几个地方使用了那个调用 fscanf 。有可能是bug吗?
  • 通常,对于经常传递不指向已分配空间的指针的 C 初学者来说,fscanf 是指针错误的主要来源。这很容易踩到其他结构。
  • @dsutandi 只显示你所有的代码,而不是让每个人都猜测。
【解决方案3】:

errno 说了什么?将此添加到您的代码中:

#include <errno.h>
#include <string.h>

if (fclose(myFile) == EOF) {
    // Handle the error!
    fprintf(stderr, "Error closing input file. and errno = %d, and error = %s\n", errno, strerror(errno));
    exit(1);
}

希望对您有所帮助。

问候。

【讨论】:

  • 错误编号为 0,显示“读取错误”。我会尝试用谷歌搜索是什么原因造成的:)谢谢!
  • @dsutandi :好的,如果您愿意,可以发布您的代码,以便我们提供帮助。
【解决方案4】:
while(myFile != EOF)
 {
 // read and process the file
 // this part works.
 }

如果这部分没问题,那么

fclose(myFile);

肯定会返回 EOF。因为 while 循环仅终止 myFile == EOF(这是一个错误的比较,请不要忽略警告)。指针和 int 之间的比较。因为 EOF 是在 stdio.h 文件中定义的宏并根据到 glibc 它 -1。您的循环终止,这意味着您的 myFile 指针更改为 EOF some whire。这是您的错误。

只需浏览您的代码,您必须更改不应被您覆盖的 FILE 指针 myFile 因为它指向文件结构 用于所有文件操作。

注意 myFile 是指向文件的指针,不应在任何赋值语句中用作左值。

【讨论】:

    【解决方案5】:

    while(myFile != EOF){...} 更改为while(!feof(myFile)){...}
    myFile 是指向 FILE 结构(内存地址)的指针。不是“文件结束”指示符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      相关资源
      最近更新 更多