Search code examples
cstdingetchar

How does the STDIN buffer and getchar() pointer change during successive calls?


Given input in the stdin buffer, when successive calls to getchar() are performed, does the pointer move along the memory address of the stdin buffer, allowing getchar() to retrieve the value at each address? If so, once they have been retrieved are the values removed and the pointer then incremented?

Generally my understanding of getchar() in a loop follows this logic:

  1. getchar() called
  2. stdin buffer checked for input
  3. If stdin buffer empty, getchar() sleeps
  4. user enters input and awakens get char()
  5. stdin buffer checked again for input
  6. stdin buffer not empty
  7. getchar() retrieves value at address at the start of the stdin buffer
  8. value at address removed from stdin buffer, pointer incremented
  9. subsequent calls repeat steps 7-8 until EOF encountered

A similar question was asked before on stackoverflow but I had trouble understanding the responses.


Solution

  • Generally there is a stdio internal buffer. getchar() may trigger a line read into the buffer, and generally on subsequent calls, it will simply increment a pointer until the pointer reaches the end of the current data in the buffer. The implementation usually uses a simple internal char * to an underlying chunk of dynamic memory, with a few pointers and state variable(s).

    Implementations vary, I don't recall the POSIX standard implying much about the internal implementation of getchar() or stdio streams in general, except that given operations should be supported.

    If I recall, some implementations are unbuffered (I think the DOS compiler I used did not buffer), but there are multiple standard lib implementations for a given OS.

    It is not uncommon to have 2 stdio libs on the same system, example: sys-admins managing AIX, Solaris, HPUX, and other non-Linux/BSD UNIX platforms will frequently install the GNU stack to get tools like gcc, and that stack includes glibc (GNU LIBC).

    You can download a libc/stdio source online. See glibc.

    If it helps, consider that stdio provides peek and unget functionality, and the only way to do that is by an internal buffer between the terminal and the user program.