简体   繁体   中英

Does EOF from fputc always mean ferror returns true?

A simple question, and I am about 99.99% sure of the answer but seeking some feedback so I can feel 100% confident in my understanding. When fputc returns EOF it is only on stream error correct? For example, say I have a very small space to write to, and the end of space is reached, fputc would return EOF as an error and not actually end-of-file? In other words, something like this is not required?

ch = fputc(c, stream);
if(ch == EOF) {
    if(ferror(stream)) {
        // error
    } else {
        // EOF
    }
}

Because if fputc returns EOF it is safe for me to assume that ferror(stream) will always return non-0?

I searched for answers on here, and I apologize if this is a duplicate question, but I am relatively new on here and haven't quite mastered the art of searching the knowledge base yet.

In this case, reading the documentation should help. See eg https://en.cppreference.com/w/c/io/fputc

Return value

On success, returns the written character.

On failure, returns EOF and sets the error indicator (see ferror() ) on stream.

There is nothing written about the literal meaning end-of-file, and this would not make sense for an output file.

Clarification: According to the ISO C standard, with fputc the return value EOF will indicate an error and not the literal meaning end-of-file. The standard doesn't specifically mention feof() here, so the return value of feof() may be undefined. To be safe you should check ferror() only.

In ¶7.21.7.3 The fputc function ¶3 , the C standard says:

The fputc function returns the character written. If a write error occurs, the error indicator for the stream is set and fputc returns EOF .

So, for fputc() , your argument is correct according to the standard. If there's no space left on the device or the output stream is closed (pipe or socket) or … then an output error has occurred, and fputc() will return EOF (eventually, when the stream flushes its buffer) and ferror() will report that the stream had an error.

The discussion would be different for fgetc() and input functions. Then ferror() tests for an error on the file stream, but feof() tests for EOF.

You should be wary of using either feof() or ferror() with input functions — notably, see while (!feof(file)) is always wrong .

Your use is acceptable — you are checking after an output function ( fputc() ) returns EOF. That would also be correct if an input function reports failure — then you can check with feof() or ferror() .

You can use clearerr() on a stream to clear the error and EOF indicators.

According to the cppreference entry for fputc() :

On failure, returns EOF and sets the error indicator (see ferror()) on stream.

This seems (to me, at least) to imply that a subsequent call to ferror() on that stream will, indeed, return a non-zero value (ie true ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM