Undoing the effects of ungetc() : “How” do fseek(),rewind() and fsetpos() do it?Is buffer refilled each time?

后端 未结 2 1786
-上瘾入骨i
-上瘾入骨i 2021-01-28 16:07

Huh!!How shall I put the whole thing in a clear question!!Let me try:

I know that the files opened using fopen() are buffered into memory.We use a buffer fo

2条回答
  •  温柔的废话
    2021-01-28 16:51

    A good mental model of the put back character is simply that it's some extra little property which hangs off the FILE * object. Imagine you have:

    typedef struct { 
       /* ... */
       int putback_char;
       /* ... */
    } FILE;
    

    Imagine putback_char is initialized to the value EOF which indicates "there is no putback char", and ungetc simply stores the character to this member.

    Imagine that every read operation goes through getc, and that getc does something like this:

    int getc(FILE *stream)
    {
       int ret = stream->putback_char;
    
       if (ret != EOF) {
         stream->putback_char = EOF;
         if (__is_binary(stream))
            stream->current_position--;
         return ret;
       }
    
       return __internal_getc(stream); /* __internal_getc doesn't know about putback_char */
    }
    

    The functions which clear the pushback simply assign EOF to putback_char.

    In other words, the put back character (and only one needs to be supported) can actually be a miniature buffer which is separate from the regular buffering. (Consider that even an unbuffered stream supports ungetc: such a stream has to put the byte or character somewhere.)

    Regarding the position indicator, the C99 standard says this:

    For a text stream, the value of its file position indicator after a successful call to the ungetc function is unspecified until all pushed-back characters are read or discarded. For a binary stream, its file position indicator is decremented by each successful call to the ungetc function; if its value was zero before a call, it is indeterminate after the call. [7.19.7.11 The ungetc function]

    So, the www.cplusplus.com reference you're using is incorrect; the behavior of ftell is not undefined when there are pending characters pushed back with ungetc. For text streams, the value is unspecified. Accessing an unspecified value isn't undefined behavior, because an unspecified value cannot be a trap representation. The undefined behavior exists for binary streams if a push back occurs at position zero, because the position then becomes indeterminate. Indeterminate means that it's an unspecified value which could be a trap representation. Accessing it could halt the program with an error message, or trigger other behaviors.

    It's better to get programming language and library specifications from the horse's mouth, rather than from random websites.

提交回复
热议问题