在循环中检查 EOF

Check EOF after fread in a loop

提问人:beardeadclown 提问时间:8/21/2021 最后编辑:beardeadclown 更新时间:8/21/2021 访问量:345

问:

我弄清楚了为什么下面的循环会给我,为什么“while ( !feof (file) )”总是错的?bad input

do {
    if (fread(buf, 1, siz, stdin) != siz) {
        if (feof(stdin))
            fputs("bad input\n", stderr);
        else /* implying ferror(stdin) */
            perror("fread() failed");
        return EXIT_FAILURE;
    }
    use(buf);
} while (!feof(stdin));

是否不可避免地编写一些辅助函数/奇怪的调用来正确(?)检查 EOF,或者有更好的方法吗?ungetc(getchar(), stdin)

C Stdin EOF 面包 Feof

评论


答:

2赞 Ture Pålsson 8/21/2021 #1

我会做这样的事情

size_t nread;
while ((nread = fread(buf, 1, siz, stdin)) == siz) {
    use(buf);
}

if (feof(stdin)) {
    if (nread == 0) {
        /* Normal EOF; do nothing. I would not actually
           write this branch. :-) */
    } else {
        /* Short read. */
        fputs("bad data\n", stderr); }
    }
} else {
    perror("fread");
} 
0赞 Andreas Wenzel 8/21/2021 #2

无需用于检查文件末尾。相反,您可以将循环重写为以下内容:ungetc

while ( fread(buf, 1, siz, stdin) == siz )
{
    use(buf);
}

//verify that the loop was terminated due to end-of-file and not due
//to stream error
if ( ferror(stdin) )
{
    perror( "fread() failed" );
    return EXIT_FAILURE;
}

//No stream error occurred, so the loop must have been terminated due
//to end-of-file. Therefore, everything is ok and we can continue
//running the program normally.

根据具体情况,您可能还需要检查是否发生了部分读取,并将其视为错误。请参阅有关如何做到这一点的其他答案。