In my current understanding, you're supposed to call ungetc
when you want to "un-get" the most recent character that you got from the stream,
That is the use implied by the function's name, yes. And in my personal experience, it is the most common use, though this is a rarely-used function overall.
Shouldn't the stream remember at least what its most recently obtained character was?
It could, but I don't see how you get from there to should. The possibility of an alternative design for rarely-used ungetc()
is pretty much the only reason for considering that.
I was thinking that it could be just ungetc(stream)
, which probably makes more sense.
It would make more sense if the function were limited to pushing back only the character most recently read from the specified stream. But in fact, there is no such limitation.
I've seen a lot of implementations that involve the use of ungetc, and so far, none of them have really shown that the function is capable of pushing back a different character
I don't find it surprising that the ungetc()
uses you have seen all push back the character that was just read. That is certainly the primary intended use case, as reflected in the function's name. But that you haven't seen examples of other uses and can't think of any is irrelevant. The function's documentation specifies that it is the character passed as an argument that is pushed back, regardless of what the most recently read character was, or if there even was one.
Possibly this design reflects a convergence of multiple goals of C's designers:
memory conservation - why make every FILE
in the system take an additional byte of RAM, of which there may be only a few thousand overall,* just to support a rarely-used function?
flexible interface - why create a system interface that can do only one specific thing when it could instead do a more general thing for little or no additional cost?
*Early C development was largely done on the PDP-11, whose minimal configuration featured a whopping 4 KB of RAM. Though I think Bell Labs' was somewhat more generously configured.