【问题标题】:fgetc(): Is it enough to just check EOF?fgetc():只检查 EOF 就足够了吗?
【发布时间】:2010-11-27 16:52:42
【问题描述】:

在网上找到的各种示例中,fgetc() 的用法如下:

FILE *fp = fopen(PATH, "r");

if (fp == NULL) {
    perror("main");
    exit(EXIT_FAILURE);
}

int ch;

while (ch = fgetc(fp) != EOF) {
    // do something
}

但是根据 fgetc() 的手册页

如果发生读取错误,则错误 应设置流的指示符, fgetc() 应返回 EOF、[CX] 和 应设置 errno 以指示错误。

所以我也需要检查一下吗?怎么做?

【问题讨论】:

  • 你需要在赋值两边加上括号:while ((ch = fgetc(fp)) != EOF),但是有了这个修复,只检查 EOF 就足够了。您将在错误或实际 EOF 上获得 EOF;如果你愿意,你可以在循环之后消除这两种情况的歧义。

标签: c file-io


【解决方案1】:

这就是规范所说的:

fgetc() 函数将获取下一个字节作为转换为 int 的无符号字符

以下宏名称应定义为负整数常量表达式:EOF

只要将返回值存储在int 而不是char 中,检查EOF 就足够了,因为它保证不代表有效的字符值。


另外,在你的代码中,这个:

while (ch = fgetc(fp) != EOF)

应该是:

while ((ch = fgetc(fp)) != EOF)

额外的括号是必需的,因为!= 的优先级高于=

【讨论】:

    【解决方案2】:

    您可以在稍后使用 ferror(3) 进行检查:

    while (EOF != (ch = fgetc(fp)))
       // do something
    
    if (ferror(fp) != 0)
       // error handling
    

    如果发生错误,ferror 返回非零值。

    如果你想在错误发生后使用 fp,你需要用 clearerr 清除错误标志:

    clearerr(fp);
    

    【讨论】:

    • @Helper 方法:您刚刚在手册页摘录中引用了该声明。
    【解决方案3】:

    循环直到fgetc 返回EOF 非常好。之后,如果您想知道循环是由于到达文件末尾还是由于错误而结束,您应该调用ferrorfeof。如果您不在乎,可以跳过通话。

    请注意,检查feof 还是ferror 很重要,因为流的错误指示符是粘性的,即使在遇到fgetc 失败的原因时,也可以评估为真。一般情况下应该使用feof来检查,如果返回false,则认为循环因新的错误而停止。

    【讨论】:

      猜你喜欢
      • 2010-09-23
      • 2012-06-18
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 2023-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多