Home > Net >  What iterates through stdin when getchar() is in a loop?
What iterates through stdin when getchar() is in a loop?

Time:05-18

This first K&R example of character io has kind of stumped me.

#include <stdio.h>
/* copy input to output; 2nd version */
main()
{
  int c;
  while ((c = getchar()) != EOF)
    putchar(c);
}

For example entering abcd will print abcd. I would expect it to only print a because the string from stdin is never stored in full inside this program, and even if it was nothing here would iterate through it.

I don't understand is how getchar() is iterating through stdin to get to the next character. Is this a function of stdin or C?

CodePudding user response:

getchar reads from a stream. That's what stdin is. A stream is a data structure which represents a sequence of data being read from or written to somewhere. A stream is not like a single variable. It is not like an array. It is not something you "iterate through". It is something you get from (or put to).

You might think of it like a deck of cards that you're using in a game. That is, you can do operations like: look at the card on the top of the deck, take the card from the top of the deck and put it in your hand, take N cards from the top of the deck and put them in your hand.

So when you see code like

while ((c = getchar()) != EOF)
    putchar(c);

using the deck-of-cards analogy you can think of this as

while ( I try to take a card from the top of the deck and I do get one )
    put the card in my hand;

Typically you can take quite a few cards. Eventually, though, the deck will be all used up, and your loop will stop.

Calling getchar is not like calling sqrt(4). If you call sqrt(4) multiple times, you get the same answer every time. But if you call getchar() multiple times, you get a different answer every time. (Formally, we say that getchar has state, and that calling it has a side effect. Specifically, each time you call getchar, it has the side effect of permanently removing one character from the stream, that is, of updating the state of the stream to record the fact that one more character has been read.)

P.S. The deck-of-cards analogy is not perfect. With a conventional data stream, there is no way to do something like taking a card from the middle of the deck, or shuffling the deck. But you can, typically, put one card back on top of the deck (this is called ungetc in C). Also, down inside, as the deck gets low, if you're reading from a file, the stdio machinery can grab a bunch of new cards (another block from the file) and stick them in at the bottom of the deck.

CodePudding user response:

You enter "abcd"

It reads 'a', checks if it is not equal to EOF. 
If not prints 'a'
Then you go to the beginning of the loop:
It reads 'b', checks if it is not equal to EOF. 
If not prints 'b'
Then you go to the beginning of the loop:
.....

It returns EOF, checks if it is not equal to EOF. 
As it is equal it terminates the wile loop

  •  Tags:  
  • c
  • Related