文件末尾总是有一个 "Nothing" 字节

There is always a "Nothing" byte at the end of file

例如这个数据文件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]$ 

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

feof 报告是否设置了 EOF 指示符,当您尝试读取超过文件末尾时会设置它。所以最后的 fgetc 读取到文件末尾, returns EOF (通常为 -1),然后 feof returns 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 returns 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.

检查是否存在读取错误