当 getchar() 处于循环中时,什么通过 stdin 进行迭代?

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

字符 io 的第一个 K&R 示例有点难倒我。

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

例如输入 abcd 将打印 abcd。我希望它只打印 a 因为来自 stdin 的字符串永远不会完整存储在这个程序中,即使这里什么都没有也会遍历它。

我不明白 getchar() 如何遍历标准输入以到达下一个字符。这是标准输入或 C 的函数吗?

您输入“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

getcharstream 读取。这就是 stdin 的意思。流是一种数据结构,表示从某处读取或写入某处的数据序列。流不像单个变量。它不像数组。这不是您“迭代”的东西。它是您 获得(或 投入 )的东西。

您可能会认为它就像您在游戏中使用的一副纸牌。也就是说,你可以做这样的操作:看牌堆顶的牌,从牌堆顶拿一张牌放在你的手上,从牌堆顶拿N张牌放在你的手上手.

所以当你看到像这样的代码时

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

使用 deck-of-cards 类比,您可以将其视为

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

通常你可以拿很多张牌。不过,最终,套牌将全部用完,您的循环将停止。

调用 getchar 不同于调用 sqrt(4)。如果你多次调用 sqrt(4),你每次都会得到相同的答案。但是,如果您多次调用 getchar(),您每次都会得到 不同的 答案。 (正式地,我们说 getcharstate,调用它有一个 side effect。具体来说,每次你调用 getchar,它具有从流中永久删除一个字符的副作用,即更新流的状态以记录已读取另一个字符的事实。)

P.S。 deck-of-cards 类比并不完美。使用传统的数据流,无法执行诸如从一副牌中间取出一张牌或洗牌之类的操作。但通常情况下,您可以将一张牌放回牌组顶部(这在 C 中称为 ungetc)。此外,在内部,当甲板变低时,如果您正在从文件中读取,stdio 机器可以抓取一堆新卡片(文件中的另一个块)并将它们粘贴在甲板底部。