cstdineoffreadfeof

Check EOF after fread in a loop


I figured out why the following loop was giving me bad input, re Why is “while ( !feof (file) )” always wrong?

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));

Is it inevitable to write some auxiliary function/weird call for properly(?) checking EOF along the lines of ungetc(getchar(), stdin) or is there a better way?


Solution

  • I'd do something like

    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");
    }