【问题标题】:There is always a "Nothing" byte at the end of file [duplicate]文件末尾总是有一个“Nothing”字节[重复]
【发布时间】:2020-04-17 11:00:48
【问题描述】:

例如这个数据文件abc.txt

abc

注意底部没有换行符。

当我用 C 编写以下程序时

#include <stdio.h>

int main(){
    FILE *fp = fopen("abc.txt","rb");  // NOTE this is "rb"

    while (!feof(fp)){
        fprintf(stdout, "%c", fgetc(fp));
        fprintf(stdout, "%d", feof(fp));
    }

    fclose(fp);

    return 0;
}

标准输出结果是这样的:

[xxx@xxx hello]$ ./a.out 
a0b0c0
0�1[xxx@xxx hello]$ 

最后一行的额外输出字节数是多少?

【问题讨论】:

    标签: c file binaryfiles eof stdio


    【解决方案1】:

    feof 报告是否设置了 EOF 指示符,并且在您尝试读取文件末尾时设置了它。所以最终的fgetc 读取到文件末尾,返回EOF(通常为-1),然后feof 返回1。

    如果您使用%d 而不是%c 来显示fgetc 的结果,这一点会更清楚:

    #include <stdio.h>
    
    int main(){
        FILE *fp = fopen("abc.txt","rb");  // NOTE this is "rb"
    
        while (!feof(fp)){
            fprintf(stdout, "%d:", fgetc(fp));
            fprintf(stdout, "%d\n", feof(fp));
        }
    
        fclose(fp);
    
        return 0;
    }
    

    输出:

    97:0
    98:0
    99:0
    -1:1
    

    我可能会编写避免feof 的代码,并使用fgetc 在出现错误或到达文件末尾时返回EOF。

    #include <stdio.h>
    
    int main(){
        FILE *fp = fopen("abc.txt","rb");  // NOTE this is "rb"
    
        while (1) {
            int c = fgetc(fp);
            if (c == EOF) break;
            printf("%c", c);
        }
    
        fclose(fp);
    
        return 0;
    }
    

    请注意,此代码仍然存在缺陷,因为它处理 EOF 之类的错误:您应该使用 ferror 检查是否存在读取错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-18
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-05
      • 2013-09-06
      • 2016-04-28
      相关资源
      最近更新 更多